代码如下:
section .data
first_num dd 0
second_num dd 0
print_fmt db '%.2lf ', 0
section .bss
result resb 8
section .text
extern printf, strtol
global main
%macro string_to_number 2
PUSH rdi
PUSH rsi
PUSH rdx
PUSH rax
mov rdi, %2
mov rsi, 0
mov rdx, 10
mov rax, 0
call strtol
mov [%1], eax
POP rax
POP rdx
POP rsi
POP rdi
%endmacro
%macro print 0
PUSH rdi
PUSH rsi
PUSH rdx
PUSH rax
mov rdi, print_fmt
mov rsi, [result]
mov rax, 0
call printf
POP rax
POP rdx
POP rsi
POP rdi
%endmacro
main:
PUSH rbp
mov rbp, rsp
cmp rdi, 3
jl .end
add rsi, 8
string_to_number first_num, [rsi]
add rsi, 8
string_to_number second_num, [rsi]
fild dword [first_num]
fsqrt
fstp qword [result] ; <--THIS
print
.end:
POP rbp
mov rax, 0
ret
程序尚未完成。我只想打印第一个命令行参数的平方根并进行测试。我使用gdb调试了所有内容,直到FSTP
命令为止,一切都正常工作。此时,正确的根位于st0
(FPU堆栈的顶部)中,并且在FSTP
命令之后,结果位置中没有写入任何内容(它为零),并且st0
为零。我不明白会发生什么。我尝试使用result
而不是FST
来更改FSTP
的大小,但没什么不同。
这是makefile:
test.o: test.asm
nasm -f elf64 -g -F dwarf test.asm -o test.o
test: test.o
gcc -o test test.o -no-pie
我正在用64位Linux编译它。
这是来自终端的复制粘贴:
linux@DESKTOP-QF0T5NR:/mnt/c/Users/Path$ gdb -q --arg build/zad5 12 13
Reading symbols from build/zad5...done.
(gdb) break 60
Breakpoint 1 at 0x4005ab: file zad5.asm, line 60.
(gdb) start
Temporary breakpoint 2 at 0x400540: file zad5.asm, line 47.
Starting program: /mnt/c/Users/Path/build/zad5 12 13
Temporary breakpoint 2, main () at zad5.asm:47
47 PUSH rbp
(gdb) continue
Continuing.
Breakpoint 1, main () at zad5.asm:60
60 fstp qword [result]
(gdb) i r f
st0 3.46410161513775438635 (raw 0x4000ddb3d742c2655000)
st1 0 (raw 0x00000000000000000000)
st2 0 (raw 0x00000000000000000000)
st3 0 (raw 0x00000000000000000000)
st4 0 (raw 0x00000000000000000000)
st5 0 (raw 0x00000000000000000000)
st6 0 (raw 0x00000000000000000000)
st7 0 (raw 0x00000000000000000000)
fctrl 0x27f 639
fstat 0x3820 14368
ftag 0x3fff 16383
fiseg 0x33 51
fioff 0x4005a9 4195753
foseg 0x2b 43
fooff 0x601038 6295608
fop 0x0 0
(gdb) p *(double*)result
$1 = 0
(gdb) next
61 print
(gdb) p *(double*)result
$2 = 0
(gdb)