为什么NA​​SM在操作数中作为符号名称的有效指令助记符有问题?

时间:2017-12-07 10:53:56

标签: 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:15: error: comma, colon, decorator or end of line expected after operand

正如我在此answer中所读到的那样,这是因为str是一个指令助记符。所以我在str添加了一个冒号,现在编译得很好。但是那条线呢

mov rsi, str

str是一个指令助记符,但它仍然编译好。为什么?

1 个答案:

答案 0 :(得分:2)

作为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...