用于打印到 stdout 的 `mov edx, Len` 是否将 "Len" 的值或地址存储到寄存器中?

Does `mov edx, Len` for printing to stdout store the value or the address of "Len" into the register?

我是汇编编程新手(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

有人告诉我 mov ecx, Msg 指令将 Msg 的地址移动到 ecx 寄存器中。

下一条指令呢 mov edx, Len?

Len 没有地址。用 equ 定义的标签只是使名称 Len 成为一种引用特定数值的便捷方式,在这种情况下,该数值由汇编程序计算并且恰好是 6。它不分配任何space 在内存中。 mov edx, Len 是立即加载,将数值 6 放入 edx 寄存器。

在某种意义上,Msg也是一种引用特定数值的便捷方式——但这里的数值恰好是某个地址内存中包含字节“Hello”的位置。所以 mov ecx, Msg 也是一个立即加载,它将那个数值放入 ecx.

如果你愿意,你可以把Msg: db "Hello", 10想成shorthand for

Msg: equ $
    db "Hello", 10

它将标签Msg设置为等于汇编程序的当前地址,然后从当前地址开始汇编一些字节。

(请注意,此答案特定于 nasm。其他 Intel 语法汇编程序通常类似;但例如,在 AT&T 语法中,指令 movl Len, %edx 是从内存中移动,相当于 Intel 的 mov edx, [Len];它会尝试从地址 6 获取四个字节,这会崩溃。在该语法中,您将改为编写 movl $Len, %edx。)