我正在将编译器编写到 NASM 程序集中,只是为了好玩,但我一直在尝试在堆栈上的数组中实现索引。
我的编译器根据下面的输入生成以下程序集。我添加了评论来解释发生了什么。
x = [1, 2, 3, 4]
exit x[1]
global _start
_start:
mov rax, 1 ; start pushing values in the array to the stack
push rax
mov rax, 2
push rax
mov rax, 3
push rax
mov rax, 4
push rax
mov rax, 0x21 ; special byte to denote the end of the array
push rax, ; finish.
mov rax, 1
push rax ; push the value from the index to the stack
pop rbx
mov rax, 8
imul rbx ; scale the offset by 8
sub rsp, rax ; remove the offset from the stack pointer
mov rax, [rax + 40] ; get the value in the array from the stack
push rax ; exit with the array value
mov rax, 60
pop rdi
syscall
这行不通。
mov rax, [rax + 40]
行会导致段错误。但是,如果我手动将该行替换为 mov rax, [rsp - 8 + 40]
,程序将按预期以 1 退出。不幸的是我不能这样做,因为无法在编译时知道索引的值。
我应该生成什么程序集才能正确索引到数组中?我天真地尝试过
mov rax, [rsp - (rax * 8) + 40]
但这是一个无效的有效地址,因为如果你逃逸缓冲区,你就无法减去寄存器。
谢谢!
正如 ErikEdit 所指出的,我以错误的方式编写了子程序。哎呀。解决这个问题解决了我的问题。