簡単なコンパイラを書こうとしています。私の言語は、浮動小数点数を使用して算術式を計算し、変数を保存し、変数を出力できます。私のコンパイラの最初のバージョンでは、すべての計算で apush
とのみを使用していましたpop
。次に、絶対スタックアドレスを呼び出して計算します。でメモリを割り当てていませんsub rsp
が、 を使用しまし[rsp-8*x]
た。ここで、はx
スタック上の値の数です。しかし問題は、libc の関数では動作しないことです。私が間違っていることを理解できません。push
pop
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
私の2番目のバージョン:
[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
、問題は解決しました。
私の質問は、なぜ私が行った変更がこの問題を解決したのですか?