我已经用谷歌搜索了足够多的东西,但无法弄清楚括号是什么()
意思。另外,我看到一些语法为movl 8(%ebp), %eax
有人可以建议我一些好的参考吗?我无法在 Google 的前 20 个结果中找到任何结果。
我已经用谷歌搜索了足够多的东西,但无法弄清楚括号是什么()
意思。另外,我看到一些语法为movl 8(%ebp), %eax
有人可以建议我一些好的参考吗?我无法在 Google 的前 20 个结果中找到任何结果。
%eax
是寄存器 EAX;(%eax)
是其地址包含在寄存器 EAX 中的内存位置;8(%eax)
是其地址为 EAX 的值加 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)
将 long 值 (dword) 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 作为(gas)文档:http ://web.archive.org/web/20080313132324/http://sourceware.org/binutils/docs-2.16/as/index.html
它们是移动指令,将数据从一个地方移动到另一个地方——在这些情况下,从内存到寄存器:
register_eax = *(unsigned long *)register_eax;
你的另一个例子是这样的:
register_eax = *(unsigned long *)(register_ebp + 8);
LaC 是对的。符号()表示寄存器的地址。%eax 是该地址的值。所以 'movl 8(%ebp), %eax' 表示将 %eax 设置为 %ebp 的地址。