我写了以下简单程序,但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手册所解释的那样,除了宏定义和指令外,nasm源线的格式具有这四个字段的一定组合:
label: instruction operands ; comment
将mov
视为助记符后,它不再考虑剩余的令牌作为可能的指令助记符。汇编语言严格每句话是一种指令。
如果您想要编码str ax
指令的字节作为mov
-Sign-Sign-extended-immm32的直接操作数,则必须使用数字常数来执行此操作。 nasm syntax nont可以为您做到这一点,因此,它的解析器一旦找到助记符就不需要反复出现。
或不用手动编码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...