我正在尝试编写一个简单的编译器。我的语言可以使用浮点数计算算术表达式,保存变量并打印变量。在我的编译器的第一个版本中,我所有的计算都只使用 apush
和pop
。然后我用调用绝对堆栈地址进行计算。我没有使用 分配内存sub rsp
,而是使用了[rsp-8*x]
,其中x
是堆栈上的值的数量,例如 apush
和pop
。但问题是它不适用于pow
libc 中的函数。我不明白,我做错了什么。
为了您的方便,我稍微重构了代码。
我的第一个汇编版本(nasm 语法):
[bits 64]
global _start
extern printf
extern pow
section .data
printf_format db '%lf', 10, 0
section .text
_start:
mov rbp, rsp
sub rsp, 0x20
mov rax, 0x4000000000000000
push rax
mov rax, 0x4000000000000000
push rax
mov rax, 0x4008000000000000
push rax
movsd xmm0, qword [rsp+8]
movsd xmm1, qword [rsp]
call pow
movsd qword [rsp+8], xmm0
add rsp, 8
movsd xmm0, qword [rsp+8]
movsd xmm1, qword [rsp]
call pow
mov rdi, printf_format
mov rax, 1
call printf
mov rax, 60
mov rdi, 0
syscall
我的第二个版本:
[bits 64]
global _start
extern printf
extern pow
section .data
printf_format db '%lf', 10, 0
section .text
_start:
mov rbp, rsp
sub rsp, 0x20
mov rax, 0x4000000000000000
mov qword [rsp-8*1], rax
mov rax, 0x4000000000000000
mov qword [rsp-8*2], rax
mov rax, 0x4008000000000000
mov qword [rsp-8*3], rax
movsd xmm0, qword [rsp-8*2]
movsd xmm1, qword [rsp-8*3]
call pow
movsd qword [rsp-8*2], xmm0
movsd xmm0, qword [rsp-8*1]
movsd xmm1, qword [rsp-8*2]
call pow
mov rdi, printf_format
mov rax, 1
call printf
mov rax, 60
mov rdi, 0
syscall
我编译并将其链接到:
nasm -f elf64 ex.asm
ld -lc -lm -m elf_x86_64 -I/lib/ld-linux-x86-64.so.2 ex.o -o ex
在我的编译器的最后一个版本中,我用 编写了调用[rsp+8*x]
并分配了sub rsp
,问题就解决了。
我的问题是:为什么我所做的改变解决了这个问题?