เหตุใด 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 เป็นตัวช่วยจำคำสั่งที่นี่ แต่ก็ยังคอมไพล์ได้ดี เพราะเหตุใด?


person St.Antario    schedule 07.12.2017    source แหล่งที่มา
comment
nasm ถือว่า 'str' เป็นป้ายกำกับอย่างชัดเจนดังนั้นจึงไม่บ่น std db 'สตริงบางส่วน' เป็นข้อผิดพลาดทางไวยากรณ์ ซึ่งพบได้ในขั้นตอนที่ 1 แล้ว ก่อนที่จะมีคนพยายามแก้ไขป้ายกำกับ str   -  person Tommylee2k    schedule 07.12.2017
comment
อ๊ะ ขออภัย คุณกำลังถามว่า ทำไม จึงไม่คอมไพล์ ไม่ซ้ำกัน. อาจเป็นผู้โหวตของคุณที่ทำให้คำตอบเก่า ๆ ที่ฉันสนใจก่อนที่ฉันจะดูสิ่งนี้: P   -  person Peter Cordes    schedule 07.12.2017
comment
คุณสามารถใช้ mov rsi, mov และ mov: db 'something' ได้และ nasm จะไม่บ่น   -  person Tommylee2k    schedule 07.12.2017


คำตอบ (1)


ตามที่ คู่มือ NASM อธิบาย นอกเหนือจากคำจำกัดความและคำสั่งระดับมหภาค รูปแบบของ NASM บรรทัดแหล่งที่มามีการรวมกันของสี่ฟิลด์เหล่านี้:

label:    instruction operands        ; comment

หลังจากที่มันเห็นว่า mov เป็นตัวช่วยจำ มันก็จะไม่ถือว่าโทเค็นที่เหลือเป็นตัวช่วยจำคำสั่งที่เป็นไปได้อีกต่อไป ภาษาแอสเซมบลีคือหนึ่งคำสั่งต่อคำสั่งอย่างเคร่งครัด

หากคุณต้องการให้ไบต์ที่เข้ารหัสคำสั่ง str ax เป็นตัวถูกดำเนินการทันทีสำหรับ mov-sign-exted-imm32 คุณจะต้องดำเนินการดังกล่าวด้วยตนเองด้วยค่าคงที่ตัวเลข ไวยากรณ์ของ NASM ไม่มี วิธีทำสิ่งนั้นให้กับคุณ ดังนั้น parser ของมันจึงไม่จำเป็นต้องเรียกซ้ำเข้าไปในตัวถูกดำเนินการเมื่อพบตัวช่วยในการจำ


หรือแทนที่จะเข้ารหัส 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...
person Peter Cordes    schedule 07.12.2017