mer*_*114 1 x86 assembly nasm cpu-registers
我是汇编编程(x86 32 位架构)的新手,对以下代码有疑问:
SECTION .data
Msg: db "Hello", 10
Len: equ $-Msg
SECTION .text
global _start
_start:
; Printing Msg to stdout
mov eax, 4
mov ebx, 1
mov ecx, Msg ; Passing the ADDRESS to the beginning of what's stored in Msg
mov edx, Len ; Are we passing the address of Len, or the value of Len?
int 80H
; Terminating
mov eax, 1
mov ebx, 0
int 80H
Run Code Online (Sandbox Code Playgroud)
有人告诉我,mov ecx, Msg指令将Msg存储位置的地址移动到ecx寄存器中。
下一条指令 mov edx, Len呢?
如果我们将Len值移动到edx寄存器,那么指令不应该以不同的方式编写,例如mov edx, [Len]?
如果我们移动地址,Len那么为什么打印消息的系统调用如此复杂?为什么需要一个寄存器来包含消息长度的地址而不是实际长度值?
Len没有地址。定义为 的标签equ只是使名称Len成为引用特定数值的便捷方式,在这种情况下,该数值由汇编器计算,恰好是 6。它不会在内存中分配任何空间。并且mov edx, Len是将数值 6 放入edx寄存器的立即加载。
从某种意义上说,Msg它也是一种引用特定数值的便捷方式——但这里的数值恰好是内存中包含字节“Hello”的某个位置的地址。所以mov ecx, Msg也立即载荷这使该数值为ecx。
如果你愿意,你可以把它Msg: db "Hello", 10看作是
Msg: equ $
db "Hello", 10
Run Code Online (Sandbox Code Playgroud)
它将标签设置为Msg等于汇编器的当前地址,然后从当前地址开始组装一些字节。
(请注意,此答案特定于 nasm。其他 Intel 语法汇编程序通常类似;但例如,在 AT&T 语法中,指令movl Len, %edx是从内存中移动,相当于 Intel 的mov edx, [Len];它会尝试从地址 6 获取四个字节, 这会崩溃。在这种语法中,您将改为编写movl $Len, %edx.)