Parsing 为什么';NASM在使用有效的指令助记符作为操作数中的符号名时有问题吗?

Parsing 为什么';NASM在使用有效的指令助记符作为操作数中的符号名时有问题吗?,parsing,assembly,compiler-construction,x86,nasm,Parsing,Assembly,Compiler Construction,X86,Nasm,我编写了以下简单的程序,但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

我编写了以下简单的程序,但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
正如我在本文中所读到的,这是因为
str
是一种指令助记符。因此,我在
str
中添加了一个冒号,现在它可以很好地编译。但是线路呢

mov rsi, str
str
在这里是一种指令助记符,但它仍然可以很好地编译。为什么?

因为,除了宏定义和指令之外,NASM源代码行的格式有以下四个字段的组合:

label:    instruction operands        ; comment
在它将
mov
视为助记符之后,它不再将剩余的令牌视为可能的指令助记符。汇编语言严格来说是每条语句一条指令

如果您希望将编码
str ax
指令的字节作为
mov
-sign-extended-imm32的直接操作数,您必须自己使用一个数值常量来完成此操作。
NASM语法无法为您完成此操作,因此,一旦找到助记符,它的解析器就不需要递归到操作数中


或者使用
db
发出
mov
指令的字节,而不是手动编码
str

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源代码行的格式包含以下四个字段的组合:

label:    instruction operands        ; comment
在它将
mov
视为助记符之后,它不再将剩余的令牌视为可能的指令助记符。汇编语言严格来说是每条语句一条指令

如果您希望将编码
str ax
指令的字节作为
mov
-sign-extended-imm32的直接操作数,您必须自己使用一个数值常量来完成此操作。
NASM语法无法为您完成此操作,因此,一旦找到助记符,它的解析器就不需要递归到操作数中


或者使用
db
发出
mov
指令的字节,而不是手动编码
str

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显然将“str”视为一个标签,因此没有抱怨。“std db'some string'”是一个语法错误,在第1步中已经发现了,在有人试图解析“str”标签操作之前,对不起,您是在问为什么它不能编译。不是复制品。在我看这篇文章之前,也许是你的一票让我注意到了这个老答案:Pyou甚至可以使用“
mov rsi,mov
”和“
mov:db'something'
”,nasm不会抱怨ASM显然将'str'视为一个标签,因此不会抱怨。“std db'some string'”是一个语法错误,在第1步中已经发现了,在有人试图解析“str”标签操作之前,对不起,您是在问为什么它不能编译。不是复制品。在我看这篇文章之前,可能是你的一票让我注意到了这个老答案:Pyou甚至可以使用“
mov rsi,mov
”和“
mov:db'something'
”而nasm不会抱怨