我正在尝试编写一个简单的编译器。我的语言可以使用浮点数计算算术表达式,保存变量并打印变量。在我的编译器的第一个版本中,我的所有计算仅使用push
和pop
。然后我用调用绝对堆栈地址进行计算。我没有使用sub rsp
分配内存,而是使用[rsp-8*x]
,其中x
是堆栈上的值数,例如push
和pop
。但问题是它不适用于libc的pow
函数。我无法理解,我做错了什么。
我在程序集中的第一个版本(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
进行了分配,问题解决了。
我的问题是:为什么我做出的改变解决了这个问题?