我已经google了足够但无法弄清括号()
的含义。另外,我看到一些语法为movl 8(%ebp), %eax
有人会建议我一些好的参考吗?我无法在Google的前20个搜索结果中找到任何结果。
答案 0 :(得分:14)
%eax
是注册EAX; (%eax)
是内存位置,其地址包含在寄存器EAX中; 8(%eax)
是内存位置,其地址是EAX加上8的值。
答案 1 :(得分:8)
http://web.archive.org/web/20080215230650/http://sig9.com/articles/att-syntax快速介绍Unix(AT& T)asm语法。用at&t asm syntax
搜索。
帖子是vivek(http://web.archive.org/web/20080228052132/http://sig9.com/blog/vivek)的“AT& T汇编语法”,2003-09-01。有关于AT& T的主要信息:
例如,INTEL语法中基本数据移动指令的一般格式是
mnemonic destination, source
然而,在AT& T的情况下,一般格式是
mnemonic source, destination
(我记得这个命令称AT& T asm是真正的Unix asm,所以它是正确一个,它将数据流向右边;而Intel语法基于一些不正确的masms doc ,显然不适合Unix世界,它们左,数据流向左侧)
IA-32架构的所有寄存器名称都必须以'%'符号为前缀,例如。 %al,%bx,%ds,%cr0等。
所有文字值必须以'$'符号为前缀。例如,
mov $100, %bx mov $A, %al
第一条指令将值100移入寄存器AX,第二条指令将ascii A的数值移入AL寄存器。
在AT& T语法中,内存以下列方式引用,
segment-override:signed-offset(base,index,scale)
根据您想要的地址,可以省略部分内容。> %ES:100(%eax中,%EBX,2)
请注意,偏移量和比例不应以“$”为前缀。使用等效的NASM语法的更多示例应该使事情更清楚,
GAS memory operand NASM memory operand ------------------ ------------------- 100 [100] %es:100 [es:100] (%eax) [eax] (%eax,%ebx) [eax+ebx] (%ecx,%ebx,2) [ecx+ebx*2] (,%ebx,2) [ebx*2] -10(%eax) [eax-10] %ds:-10(%ebp) [ds:ebp-10] Example instructions, mov %ax, 100 mov %eax, -100(%eax)
操作数大小。有时,特别是在将文字值移动到内存时,需要指定传输大小或操作数大小。例如,指令,
mov $10, 100
仅指示将值10移动到存储器偏移量100,而不是传输大小。在NASM中,这是通过将转换关键字byte / word / dword等添加到任何操作数来完成的。在AT& T语法中,这是通过向指令添加后缀-b / w / l来完成的。例如,
movb $10, %es:(%eax)
将字节值10移动到内存位置[ea:eax],而
movl $10, %es:(%eax)
将长值(双字)10移动到同一个地方。
jmp,call,ret等指令将控件从程序的一个部分转移到另一个程序。它们可以被分类为对相同代码段(附近)或不同代码段(远)的控制转移。分支寻址的可能类型是 - 相对偏移(标签),寄存器,存储器操作数和段偏移指针。
使用标签指定相对偏移,如下所示。
label1: . . jmp label1
使用寄存器或存储器操作数的分支寻址必须以'*'为前缀。要指定“远”控制传输,必须为'l'添加前缀,如'ljmp','lcall'等。例如,
GAS syntax NASM syntax ========== =========== jmp *100 jmp near [100] call *100 call near [100] jmp *%eax jmp near eax jmp *%ecx call near ecx jmp *(%eax) jmp near [eax] call *(%ebx) call near [ebx] ljmp *100 jmp far [100] lcall *100 call far [100] ljmp *(%eax) jmp far [eax] lcall *(%ebx) call far [ebx] ret retn lret retf lret $0x100 retf 0x100
使用以下格式指定段偏移指针:
jmp $segment, $offset
他还建议将gnu作为(气体)文档:http://web.archive.org/web/20080313132324/http://sourceware.org/binutils/docs-2.16/as/index.html
答案 2 :(得分:3)
他们移动指令,将数据从一个地方移动到另一个地方 - 在这些情况下,从内存到寄存器:
register_eax = *(unsigned long *)register_eax;
你的另一个例子是:
register_eax = *(unsigned long *)(register_ebp + 8);