Parsing 为什么';NASM在使用有效的指令助记符作为操作数中的符号名时有问题吗?
我编写了以下简单的程序,但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
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不会抱怨