linux汇编,汇编语言基于linux

  linux汇编,汇编语言基于linux

  我第一次接触AT T格式的汇编代码的时候,很多程序员都觉得太晦涩了。没关系。在Linux平台上,还可以使用Intel格式编写汇编程序:

  2.英特尔格式

  ;hello.asm

  部分。数据;段声明

  msg db“你好,世界!”,0xA要输出的字符串。

  len equ $-msg;字符串长度

  部分。文本;代码声明

  全局_开始;指定入口函数

  _ start:在屏幕上显示一个字符串。

  mov edx,len参数三:字符串长度

  mov ecx,msg参数2:要显示的字符串。

  mov ebx,1;参数1:文件描述符(标准输出)

  mov eax,4;系统调用号(sys_write)

  int0x80调用内核函数

  ;退出程序

  mov ebx,0;参数1:退出代码

  mov eax,1;系统调用号(sys_exit)

  int0x80调用内核函数

  虽然上面两个汇编器采用了完全不同的语法,但是它们的功能都是调用Linux内核提供的sys_write来显示一个字符串,然后调用sys_exit来退出程序。在Linux内核源文件include/asm-i386/unistd.h中,可以找到所有系统调用的定义。

  四。Linux汇编工具

  虽然Linux下有很多种汇编工具,像DOS/Windows,但最基本的还是汇编器,连接器,调试器。

  1.装配工

  汇编程序的作用是将汇编语言编写的源程序转换成二进制形式的目标代码。Linux平台的标准汇编器是GAS,它是GCC所依赖的后台汇编器,通常包含在binutils软件包中。GAS标准AT T汇编语法可用于汇编以AT T格式编写的程序:

  [xiaowp@gary码]$ as -o hello.o hello.s

  Linux平台上另一个常用的汇编器是NASM,它提供了很好的宏指令功能,可以支持相当多的目标代码格式,包括bin、a.out、coff、elf、rdf等。NASM使用手工编写的解析器,所以它的执行速度比GAS快得多。更重要的是,它使用英特尔汇编语法,可用于编译以英特尔语法格式编写的汇编程序:

  [xiaowp @ Gary code]$ nasm-f elf hello . ASM

  2.连接物

  汇编器生成的目标代码不能直接在计算机上运行,必须经过链接器处理才能生成可执行代码。链接器(Linker)通常用于将多个目标代码链接成一个可执行代码,这样就可以将整个程序分成几个独立开发的模块,然后将它们组合(链接)成一个应用程序。Linux ld被用作标准链接器,它也包含在binutils软件包中。在汇编程序通过GAS或NASM成功编译并生成目标代码后,可以使用ld:

  【小武@加里码】$ ld -s -o hello hello.o

  3.调试器

  有人说程序不是编译而是调用,可见调试在软件开发中的重要作用,尤其是用汇编语言编程时。在Linux下调试汇编代码可以使用GDB、DDD等通用调试器,也可以使用专门用于调试汇编代码的ALD(汇编语言调试器)。

  从调试的角度来看,使用GAS的好处是可以在生成的目标代码中包含符号表,这样就可以使用GDB和DDD进行源代码级的调试。要将符号表包含在生成的可执行程序中,可以通过以下方式进行编译和链接:

  [xiaowp @ Gary code]$ as-gstabs-o hello . o hello . s

  [小p@gary码]$ ld -o hello hello.o

  当作为命令执行时,带参数- gstabs可以告诉汇编程序在生成的目标代码中添加符号表。同时需要注意的是,用ld命令链接时,不要加-s参数,否则链接时会删除目标代码中的符号表。

  在GDB和DDD调试汇编代码和调试C语言代码是一样的。可以通过设置断点来中断程序,检查变量和寄存器的当前值,一步跟踪代码。图1是在DDD调试汇编代码时的场景:

  图1在DDD调试汇编程序

  汇编程序员通常会面临一些比较恶劣的软硬件环境,简短的ALD可能更符合实际需要,下面就介绍一下如何用ALD调试汇编程序。首先,在命令行模式下执行ald命令来启动调试器。该命令的参数是要调试的可执行程序:

  [xiaowp@gary doc]$ ald你好

  汇编语言调试器0.1.3

  版权所有2000-2002帕特里克阿尔肯

  你好:ELF Intel 80386 (32位),LSB,可执行,版本1(当前)

  加载调试符号.(加载了15个符号)

  肾上腺脑白质营养不良

  当ALD出现提示时,用反汇编命令反汇编代码段:

  ald拆解-不锈钢

  分解部分。文本(0x08048074 -0x08048096)

  08048074 BA0F000000 mov edx,0xf

  08048079 B998900408 mov ecx,0x8049098

  0804807E BB01000000 mov ebx,0x1

  08048083 B804000000 mov eax,0x4

  08048088 CD80 int0x80

  0804808A BB00000000 mov ebx,0x0

  0804808F B801000000 mov eax,0x1

  08048094 CD80 int0x80

  上面输出信息的第一列是指令对应的地址码,可以用来设置程序执行时的断点:

  ald中断0x08048088

  为0x08048088设置了断点1

  设置断点后,使用run命令开始执行程序。当ALD遇到断点时,它会自动暂停程序并显示所有寄存器的当前值:

  ald运行

  启动程序:你好

  在0x08048088处遇到断点1

  eax=0x 000000004 ebx=0x 00000001 ecx=0x 08049098 EDX=0x 0000000 f

  esp=0x bffff 6 c 0 ebp=0x 00000000 ESI=0x 00000000 EDI=0x 00000000

  ds=0x 00000002 b es=0x 00000002 b fs=0x 00000000 GS=0x 00000000

  ss=0x 00000002 b cs=0x 00000023 EIP=0x 08048088 e flags=0x 00000246

  旗帜:PF ZF IF

  08048088 CD80 int0x80

  如果需要逐句通过汇编代码,可以使用下一个命令:

  ald下一步

  你好,世界!

  eax=0x 00000000 f ebx=0x 00000000 ecx=0x 08049098 EDX=0x 0000000 f

  esp=0x bffff 6 c 0 ebp=0x 00000000 ESI=0x 00000000 EDI=0x 00000000

  ds=0x 00000002 b es=0x 00000002 b fs=0x 00000000 GS=0x 00000000

  ss=0x 00000002 b cs=0x 00000023 EIP=0x 0804808 f e flags=0x 00000346

  标志:PF ZF TF IF

  0804808F B801000000 mov eax,0x1

  有关ALD支持的所有调试命令的详细列表,您可以使用help命令:

  ald帮助

  命令可以缩写。

  如果输入空白命令,则重复最后一个命令。

  键入“help command”以获取有关该命令的更多具体信息。

  通用命令

  连接清除继续分离拆解

  输入检查文件帮助加载

  下一次退出寄存器运行设置

  分步卸载窗口写入

  断点相关命令

  中断删除禁用启用忽略

  l断路器t断路器

  动词(verb的缩写)系统调用

  即使是最简单的汇编程序也不可避免地会用到输入、输出和退出等操作。要执行这些操作,需要调用操作系统提供的服务,也就是系统调用。除非你的程序只执行加减乘除等数学运算,否则很难避免使用系统调用。其实除了系统调用不同,各种操作系统的汇编编程往往非常相似。

  Linux平台下使用系统调用有两种方式:使用打包的C库(libc)或者直接通过汇编调用。其中,通过汇编语言直接调用系统调用是使用Linux内核服务最高效的方式,因为最终生成的程序不需要与任何库链接,而是直接与内核通信。

  就像DOS一样,Linux下的系统调用是通过中断(int0x80)来实现的。执行int 80指令时,系统调用的函数号存储在寄存器eax中,传递给系统调用的参数必须依次放入寄存器ebx、ecx、edx、esi、edi中。系统调用完成后,可以在寄存器eax中获取返回值。

  的所有系统调用函数号都可以在文件/usr/include/bits/syscall.h中找到,为了方便起见,都是用SYS_ name这样的宏来定义的,比如SYS_write、SYS_exit等。例如,常用的写函数定义如下:

  ssize_t write(int fd,const void *buf,size _ t count);

  分别代表寄存器eax、ebx、ecx和edx

  s和d

  寄存器esi、edi

  我

  常数(0到31)

  八。摘要

  Linux操作系统是用C语言编写的,只有在必要的时候才会想到汇编,但汇编是减少代码量、优化代码性能的一个非常重要的手段,尤其是在直接与硬件交互的时候,汇编可以说是最好的选择。Linux提供了优秀的工具支持汇编程序的开发,使用GCC进行内联汇编可以充分发挥C语言和汇编语言各自的优势。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: