AT&T格式 | Intel格式 |
push%eax | pusheax |
AT&T格式 | Intel格式 |
pushl$1 | push1 |
AT&T格式 | Intel格式 |
addl $1,%eax | add eax,1 |
AT&T格式 | Intel格式 |
movb val,%al | mov al, byte ptrval |
1.
最为前缀,而在Intel格式中则不需要。
2.
AT&T格式 | Intel格式 |
ljump $section,$offset | jmp farsection:offset |
lcall $section,$offset | call farsection:offset |
AT&T格式 | Intel格式 |
lret$stack_adjust | ret farstack_adjust |
section:disp(base, index,scale) |
section:[base + index* scale +disp] |
disp + base + index * scale |
AT&T格式 | Intel格式 |
movl –4(%ebp),%eax | mov eax,[ebp-4] |
movl array(,%eax,4), %eax | mov eax,[eax*4 +array] |
movw array(%ebx,%eax, 4), %cx | mov cx,[ebx +4*eax + array] |
movb $4,%fs:(%eax) | movfs:eax, 4 |
AT&T格式的Hello, World
Linux汇编工具
Linux平台下汇编工具仍然是汇编器、链接器和调试器
汇编器
汇编器(assembler)作用是将汇编语言编写的源程序转换成二进制形式的目标代码。Linux平台的标准汇编器是GAS,使用AT&T汇编语法。
Linux平台下另一个常用到的汇编器是NASM,提供了很好的宏指令功能,并支持相当多的目标代码格式,包括bin,a.out, coff, elf, rdf等。NASM使用Intel汇编语法。
链接器
链接器用来将多个目标代码连接成一个可执行代码。Linux下使用ld作为标准的链接程序。
调试器
Linux下汇编代码既可以用GDB,GDD等通用调试器,也可以用专门用来调试汇编代
码的ALD(Assembly Language Debugger)。
系统调用
程序中一般都会用到输入、输出及退出等操作。这些操作可通过系统调用来完成,即通过调用操作系统提供的服务来完成。Linux下可通过封装的C库(libc)或者汇编直接调用。通过系统调用的方法高效,因为最终生成的程序不需要与任何库进行链接,而是直接和内核通信。与DOS一样,Linux下系统调用也是通过中断(int0x80)来完成。系统功能号在eax中,传递的参数使用寄存器参数传递,按顺序存放在ebx,ecx, edx, esi, edi中,调用完毕,返回值在eax中。系统功能号在/usr/includes/bits/syscall.h中,可用SYS_<name>宏来定义。当系统调用的参数个数大于5时,系统调用功能号仍然保存在eax中,全部参数依次保存在一块连续的内存区中,同时寄存器ebx保存指向该内存区域的指针。返回值保存在寄存器eax中。可以像普通函数调用一样使用栈(stack)来传递系统调用的参数。Linux采用c语言的调用模式,所有的参数必须以相反的顺序进栈,即最后一个参数先入栈,第一个参数最后进栈。如果采用栈来传递系统调用的所需的参数,执行int0x80时将栈指针复制到寄存器ebx中。
命令行参数
Linux操作系统中,一个可执行程序通过命令行启动时,所需的参数保存在栈中:
首先是argc,然后是指向各个命令行参数的指针数组argv,最后是指向环境变量的
指针数据envp。
Linux嵌入式汇编
嵌入式汇编的基本格式是:
:输出寄存器
:输入寄存器
:会被修改的寄存器);
其中,汇编语句是放汇编语言的地方;输出寄存器表示那些寄存器存放数据,这些寄存器分别对应一个C语言表达式或一个内存地址;输入寄存器表示开始执行汇编代码时,指定的一些寄存器中应存放的输入值,也分别对应一个C变量或常数值。
({
res;})
嵌入汇编语言宏函数常作为一个宏,用圆括号括住的组合语句(花括号中的语句)可以作为表达式使用。:”=a”(__res)表示代码运行结束后将eax所代表的寄存器的值放入__res变量中,作为本函数的输出值,”=a”中的”a”叫加载码,”=”表示这是一个输出寄存器。”””(seg),“m”(*(addr)))为输入寄存器,其中”””表示使用与上面同个位置的输出寄存器。而”m”(*(addr))表示一个内存偏移地址值。为了在汇编语句中使用该地址值,嵌入式汇编规定把输入和输出寄存器统一按顺序编号,顺序是从输出寄存器从左到右从上到下以”%0”开始,依次记为%0,%1, %2,…。
常用寄存器加载代码说明
代码 | 说明 | 代码 | 说明 |
a | eax | m | 使用内存地址 |
b | ebx | o | 使用内存地址并加偏移值 |
c | ecx | I | 使用常数0-31 |
d | edx | J | 使用常数0-63 |
S | 使用esi | K | 使用常数0-255 |
D | 使用edi | L | 使用常数0-65535 |
q | 使用动态分配字节可寻址寄存器(eax, ebx, ecx或edx) | M | 使用常数0-3 |
r | 使用任意动态分配的寄存器 | N | 使用1字节常数(0-255) |
g | 使用通用有效的地址即可(eax, ebx, ecx, edx或内存变量) | O | 使用常数0-31 |
A | 使用eax与edx联合(64位) |
联系客服