方括号在x86汇编中的含义是什么?

ine*_*ero 4 memory x86 assembly intel-syntax

我对装配很新,并且有一些非常基本的问题.

这四个命令有什么区别?

mov ebx, eax
mov [ebx], eax
mov ebx, [eax]
mov [ebx], [eax]
Run Code Online (Sandbox Code Playgroud)

他们说括号的意思是"得到地址的价值".但那么,第一线真正做到了什么呢?它不会将eax的价值转移到ebx吗?如果是这样,那么括号的重点是什么?

J..*_*... 7

让我们举一个非常简单的例子,假设我们有一个只有两个寄存器的CPU,EAX和EBX.

mov ebx,eax

只需将值复制eaxebx寄存器中即可

 | EAX : 0123456 |   ---->   | EAX : 0123456 |
 | EBX : 0000000 |   ====>   | EBX : 0123456 |
Run Code Online (Sandbox Code Playgroud)

现在让我们添加一些内存空间

ADDRESS         VALUE
000000          6543210
000004          5189784
000008          1698791
00000C          9816517
000010          9816875
000014          5498156
Run Code Online (Sandbox Code Playgroud)

mov [ebx],eax

将值移入eax包含的内存地址ebx.

 | EAX : 0123456 |   --no-->   | EAX : 0123456 |
 | EBX : 0000008 | --change--> | EBX : 0000008 |

ADDRESS         VALUE           VALUE
000000          6543210   ----> 6543210   
000004          5189784   ----> 5189784   
000008          1698791   ====> 0123456
00000C          9816517   ----> 9816517   
000010          9816875   ----> 9816875   
000014          5498156   ----> 5498156   
Run Code Online (Sandbox Code Playgroud)

mov ebx,[eax]

从移动中所含的内存地址的值eaxebx.

 | EAX : 0000008 |   ---->   | EAX : 0000008 |
 | EBX : 0123456 |   ====>   | EBX : 1698791 |

ADDRESS         VALUE    
000000          6543210    
000004          5189784  
000008          1698791  
00000C          9816517   
000010          9816875    
000014          5498156    
Run Code Online (Sandbox Code Playgroud)

mov [ebx],[eax]

最后,您会认为将值从包含的内存地址移动到包含在eax其中的内存地址ebx.

 | EAX : 0000008 |   --no-->   | EAX : 0000008 |
 | EBX : 000000c | --change--> | EBX : 000000c |

ADDRESS         VALUE           VALUE
000000          6543210   ----> 6543210   
000004          5189784   ----> 5189784   
000008          1698791   ----> 1698791   
00000C          9816517   ====> 1698791   
000010          9816875   ----> 9816875   
000014          5498156   ----> 5498156 
Run Code Online (Sandbox Code Playgroud)

但x86架构不允许这种组合. 你不能从内存移动到内存.

因此,括号的使用等同于解除引用操作.

  • @DannyS:[为什么不允许从内存到内存的 movl?](/sf/ask/2365591861/) 详细说明了为什么它不能编码为机器代码。GAS 手册没有详细说明它,因为它不是完整的 ISA 手册;只是为了*语法*。无论语法如何,ISA 规则都是相同的。 (2认同)

zx4*_*485 5

,您在指令中缺少操作数分隔符。我还不知道有哪个汇编程序没有它。我在引号中修正了这一点。

在 x86 汇编中,一些寄存器可以用作数据寄存器地址寄存器(与其他体系结构的区别)。这些寄存器称为 GPR(“通用寄存器”)。它们可以包含 32 位值32 位地址。他们的名字是EAXEBXECXEDXESIEDIESPEBP

移动 ebx, eax

确实将值EAX移至EBX.

mov [ebx], eax

确实将值移入EAX32 位地址指向的 32 位 DWORD 值EBX

mov ebx, [eax]

确实将 32 位地址指向的 32 位 DWORD 值EAX移至EBX

mov [ebx], [eax]

是 32 位 Intel 汇编中的无效指令,因为 x86 机器代码不支持在一条指令中使用两个任意内存操作数,仅在至少一个内存操作数是隐式的特殊情况下支持,例如在 处读取push dword [ebx]内存[ebx]和在 处写入内存[esp - 4]。请参阅哪些 x86 指令需要两个(或更多)内存操作数?


归档时间:

查看次数:

3232 次

最近记录:

7 年,8 月 前