为什么 NASM 不能将有效的指令助记符作为操作数中的符号名称?
Why doesn't NASM have trouble with valid instruction mnemonics as symbol names in operands?
我写了下面这个简单的程序,但是nasm拒绝编译。
section .text
global _start
_start:
mov rax, 0x01
mov rdi, 0x01
mov rsi, str
mov rdx, 0x03
syscall
mov rax, 60
syscall
segment .data
str db 'Some string'
nasm -f elf64 main.asm
main.asm:15: error: comma, colon, decorator or end of line expected after operand
正如我读到的 answer 这是因为 str
是一个指令助记符。所以我在 str
中添加了一个冒号,现在它可以正常编译了。但是这条线呢
mov rsi, str
str
是这里的指令助记符,但它仍然可以正常编译。为什么?
与 the NASM manual explains 一样,除了宏定义和指令之外,NASM 源代码行的格式包含以下四个字段的某种组合:
label: instruction operands ; comment
将mov
视为助记符后,不再将剩余的标记视为可能的指令助记符。汇编语言严格来说是一条指令一条语句。
如果你想要编码 str ax
指令的字节作为 mov
-sign-extended-imm32 的直接操作数,你必须自己做一个数字常量。 NASM 语法没有办法为你做到这一点,所以它的解析器不需要在找到助记符后递归到操作数中。
或者不用手动编码 str
,而是使用 db
发出 mov
指令的字节。
db 0x48, 0xc7, 0xc6 ; REX.W prefix, opcode for mov r/m64,imm32, ModR/M = rsi destination
str [rax+1] ; a disp8 makes this 4 bytes long.
;; same machine code as
mov rsi, strict dword 0x0148000f ; str [rax+1]
;; nasm optimizes it to mov esi, imm32 without strict dword.
;; I guess I should have used that 5-byte instruction for the DB version...
我写了下面这个简单的程序,但是nasm拒绝编译。
section .text
global _start
_start:
mov rax, 0x01
mov rdi, 0x01
mov rsi, str
mov rdx, 0x03
syscall
mov rax, 60
syscall
segment .data
str db 'Some string'
nasm -f elf64 main.asm
main.asm:15: error: comma, colon, decorator or end of line expected after operand
正如我读到的 answer 这是因为 str
是一个指令助记符。所以我在 str
中添加了一个冒号,现在它可以正常编译了。但是这条线呢
mov rsi, str
str
是这里的指令助记符,但它仍然可以正常编译。为什么?
与 the NASM manual explains 一样,除了宏定义和指令之外,NASM 源代码行的格式包含以下四个字段的某种组合:
label: instruction operands ; comment
将mov
视为助记符后,不再将剩余的标记视为可能的指令助记符。汇编语言严格来说是一条指令一条语句。
如果你想要编码 str ax
指令的字节作为 mov
-sign-extended-imm32 的直接操作数,你必须自己做一个数字常量。 NASM 语法没有办法为你做到这一点,所以它的解析器不需要在找到助记符后递归到操作数中。
或者不用手动编码 str
,而是使用 db
发出 mov
指令的字节。
db 0x48, 0xc7, 0xc6 ; REX.W prefix, opcode for mov r/m64,imm32, ModR/M = rsi destination
str [rax+1] ; a disp8 makes this 4 bytes long.
;; same machine code as
mov rsi, strict dword 0x0148000f ; str [rax+1]
;; nasm optimizes it to mov esi, imm32 without strict dword.
;; I guess I should have used that 5-byte instruction for the DB version...