`movl(%eax),%eax`中的括号是什么意思?

Lor*_*oh. 9 x86 assembly gnu gnu-assembler att

我已经google了足够的但无法弄清楚括号的()含义.另外,我看到一些语法movl 8(%ebp), %eax

有人可以给我一些很好的参考吗?我无法在Google的前20名搜索结果中找到任何结果.

LaC*_*LaC 18

%eax注册EAX; (%eax)是地址包含在寄存器EAX中的存储单元; 8(%eax)是内存位置,其地址是EAX加8的值.


osg*_*sgx 9

http://web.archive.org/web/20080215230650/http://sig9.com/articles/att-syntax快速介绍了Unix(AT&T)asm语法.用Google搜索at&t asm syntax.

该帖子是vivek的"AT&T汇编语法"(http://web.archive.org/web/20080228052132/http://sig9.com/blog/vivek),2003-09-01.有关于AT&T的主要信息:

例如,INTEL语法中基本数据移动指令的一般格式是,

mnemonic    destination, source
Run Code Online (Sandbox Code Playgroud)

而在AT&T的情况下,一般格式是

mnemonic    source, destination
Run Code Online (Sandbox Code Playgroud)

(我记得这个命令称AT&T asm是真正的Unix asm,所以它是正确的,它将数据流向右边;而Intel语法是基于一些不正确的masms doc,这显然不适合Unix世界,它们是向左,数据流向左侧)

IA-32架构的所有寄存器名称都必须以'%'符号为前缀,例如.%al,%bx,%ds,%cr0等

所有文字值必须以"$"符号为前缀.例如,

mov $100,   %bx
mov $A, %al
Run Code Online (Sandbox Code Playgroud)

第一条指令将值100移入寄存器AX,第二条指令将ascii A的数值移入AL寄存器.

在AT&T语法中,内存以下列方式引用,

segment-override:signed-offset(base,index,scale)
Run Code Online (Sandbox Code Playgroud)

部分可以省略,具体取决于您想要的地址.>%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)
Run Code Online (Sandbox Code Playgroud)

操作数大小.有时,特别是在将文字值移动到内存时,需要指定传输大小或操作数大小.例如说明,

mov    $10,    100
Run Code Online (Sandbox Code Playgroud)

仅指示将值10移动到存储器偏移100,而不是传输大小.在NASM中,这是通过将转换关键字byte/word/dword等添加到任何操作数来完成的.在AT&T语法中,这是通过在指令中添加后缀-b/w/l来完成的.例如,

movb    $10,    %es:(%eax)
Run Code Online (Sandbox Code Playgroud)

将字节值10移动到内存位置[ea:eax],而,

movl    $10,    %es:(%eax)
Run Code Online (Sandbox Code Playgroud)

将长值(dword)10移动到同一个地方.

jmp,call,ret等指令将控件从程序的一个部分转移到另一个程序.它们可以被分类为对相同代码段(附近)或不同代码段(远)的控制转移.分支寻址的可能类型是 - 相对偏移(标签),寄存器,存储器操作数和段偏移指针.

相对偏移量使用标签指定,如下所示.

label1:
    .
    .
  jmp   label1
Run Code Online (Sandbox Code Playgroud)

使用寄存器或存储器操作数的分支寻址必须以'*'为前缀.要指定"远"控制传输,必须为'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
Run Code Online (Sandbox Code Playgroud)

段偏移指针使用以下格式指定:

jmp    $segment, $offset
Run Code Online (Sandbox Code Playgroud)

他还建议将gnu作为(气体)文档:http://web.archive.org/web/20080313132324/http: //sourceware.org/binutils/docs-2.16/as/index.html