11

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

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

4

4 回答 4

21

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

于 2011-07-25T17:28:07.817 回答
11

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

于 2011-07-25T17:31:40.340 回答
3

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

register_eax = *(unsigned long *)register_eax;

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

register_eax = *(unsigned long *)(register_ebp + 8);
于 2011-07-25T17:32:21.020 回答
-1

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

于 2021-11-08T20:25:14.857 回答