【问题标题】:What does the bracket in `movl (%eax), %eax` mean?`movl (%eax), %eax` 中的括号是什么意思?
【发布时间】:2011-10-12 19:03:09
【问题描述】:

我已经用谷歌搜索了足够多的东西,但无法弄清楚括号 () 的含义。另外,我看到一些语法为movl 8(%ebp), %eax

有人可以给我一些好的参考吗?我在 Google 的前 20 个结果中找不到任何结果。

【问题讨论】:

  • 可能阻碍搜索的是 AT&T 和 Intel 有自己的汇编版本——这是 AT&T 语法。
  • 我已经想通了,但我找不到一个体面的参考资料来解释所有 GNU AS 语法。

标签: assembly x86 gnu-assembler att addressing-mode


【解决方案1】:

%eax 是寄存器 EAX; (%eax) 是其地址包含在寄存器 EAX 中的内存位置; 8(%eax)是地址为EAX值加8的内存位置。

【讨论】:

  • 加8什么? 8 个字节?
  • 不是 8 个字节,只是 8,数字 8。假设 %eax 包含值 0x01,(%eax) 表示索引 0x01 处的内存位置,因此 8(%eax) 表示内存位置索引 0x09。
【解决方案2】:

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) 于 2003-09-01 撰写的“AT&T 汇编语法”。其中有关于 AT&T 的主要信息:

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

mnemonic    destination, source

而对于 AT&T,一般格式是

mnemonic    source, destination

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

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)

将长值(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

【讨论】:

【解决方案3】:

它们是 move 指令,将数据从一个地方移动到另一个地方 - 在这些情况下,从内存到寄存器:

register_eax = *(unsigned long *)register_eax;

你的另一个例子是这样的:

register_eax = *(unsigned long *)(register_ebp + 8);

【讨论】:

    【解决方案4】:

    LaC 是对的。 符号()表示寄存器的地址。 %eax 是该地址的值。 所以 'movl 8(%ebp), %eax' 表示将 %eax 设置为 %ebp 的地址。

    【讨论】:

    猜你喜欢
    • 2012-08-08
    • 2015-01-25
    • 2014-03-02
    • 1970-01-01
    • 1970-01-01
    • 2011-02-11
    相关资源
    最近更新 更多