0

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

便宜上、コードを少しリファクタリングしました。

アセンブリの最初のバージョン (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、問題は解決しました。

私の質問は、なぜ私が行った変更がこの問題を解決したのですか?

4

0 に答える 0