在 NASM 语法中(与 MASM 语法不同)mov rsi, symbol
把address将符号转换为 RSI。 (使用 64 位绝对立即数效率低下;使用 RIP 相对 LEA 或mov esi, symbol
反而。如何在 GNU 汇编器中将函数或标签的地址加载到寄存器中 https://stackoverflow.com/questions/57212012/how-to-load-address-of-function-or-label-into-register-in-gnu-assembler/57212627#57212627)
mov rsi, [symbol]
将加载 8 个字节,起始位置为symbol
。当您编写这样的指令时,您可以选择一个有用的位置来加载 8 个字节。
mov rsi, msg ; rsi = address of msg. Use lea rsi, [rel msg] instead
movzx eax, byte [rsi+1] ; rax = 'e' (upper 7 bytes zeroed)
mov edx, [msg+6] ; rdx = ' wor' (upper 4 bytes zeroed)
请注意,您可以使用mov esi, msg
因为符号地址始终适合 32 位(在默认的“小”代码模型中,所有静态代码/数据都位于虚拟地址空间的低 2GB 中)。 NASM 通过汇编时间常量(例如mov rax, 1
),但可能不能使用链接时间常量。为什么 32 位寄存器上的 x86-64 指令会将整个 64 位寄存器的上部清零? https://stackoverflow.com/questions/11177137/why-do-most-x64-instructions-zero-the-upper-part-of-a-32-bit-register
写入 1 个符号后,它会更改为下一个符号的存储位置吗?
不,如果你想要的话,你必须这样做inc rsi
。没有魔法。指针只是您可以像任何其他整数一样操作的整数,而字符串只是内存中的字节。
访问寄存器并不会神奇地修改它们。
有类似的说明lodsb
and pop
从内存加载并增加一个指针(rsi
or rsp
分别),但 x86 没有任何前/后递增/递减寻址模式,因此您无法使用mov
即使你想要它。使用add
/sub
or inc
/dec
.