0
我試圖使用NASM風格的x86彙編打印出一些32位浮點數。這是我想要做的最小工作示例:使用printf在x86 nasm中打印浮點數32位
global main
extern printf, scanf
section .data
scan_format: db "%f",0
print_format: db "%f",0xA,0
section .bss
result_num: resb 4
section .text
main:
push result_num
push scan_format
call scanf
add esp, 8
push dword [result_num]
push print_format
call printf
add esp, 8
ret
當我運行它,我得到一些奇怪的輸出:
$ nasm -felf32 -g printf_test.asm
$ gcc printf_test.o -o printf_test.out
$ ./printf_test.out <<< 1234
-0.000000
如果我嘗試檢查,而該計劃的價值它似乎是正確的:
$ gdb ./printf_test.out
(gdb) disassemble *main
Dump of assembler code for function main:
0x08048420 <+0>: push 0x804a028
0x08048425 <+5>: push 0x804a018
0x0804842a <+10>: call 0x8048330 <[email protected]>
0x0804842f <+15>: add esp,0x8
0x08048432 <+18>: push DWORD PTR ds:0x804a028
0x08048438 <+24>: push 0x804a01b
0x0804843d <+29>: call 0x8048320 <[email protected]>
0x08048442 <+34>: add esp,0x8
0x08048445 <+37>: ret
0x08048446 <+38>: nop
0x08048447 <+39>: nop
0x08048448 <+40>: nop
0x08048449 <+41>: nop
0x0804844a <+42>: nop
0x0804844b <+43>: nop
0x0804844c <+44>: nop
0x0804844d <+45>: nop
0x0804844e <+46>: nop
0x0804844f <+47>: nop
End of assembler dump.
(gdb) break *main+34
Breakpoint 1 at 0x8048442
(gdb) r
Starting program: /vagrant/project_03/printf_test.out
1234
-0.000000
Breakpoint 1, 0x08048442 in main()
(gdb) p /f result_num
$1 = 1234
我在做什麼錯在這裏?
編輯
如果我嘗試使用雙打,它甚至不會安裝,該程序:
global main
extern printf, scanf
section .data
scan_format: db "%f",0
print_format: db "%f",0xA,0
section .bss
result_num: resb 4
result_num_dub: resb 8
section .text
main:
push result_num
push scan_format
call scanf
add esp, 8
fld dword [result_num]
fstp qword [result_num_dub]
push qword [result_num_dub] ;ASSEMBLER ERROR HERE
push print_format
call printf
add esp, 8
ret
生成的輸出:
$ nasm -felf32 -g printf_test.asm
printf_test.asm:22: error: instruction not supported in 32-bit mode
如果我嘗試去直接從浮動堆棧到內存堆棧,我得到一個段錯誤,即使正確的東西似乎存儲在內存中。
fld dword [result_num]
fstp qword [esp]
push format
call printf
它看起來就在GDB:
(gdb) p *((double*)($esp))
$9 = 2.5
但它產生的printf的調用的中間段錯誤。我不得不丟失一些東西。
不''printf'希望'%f'說明符有'double'參數嗎? (請參閱「說明符」表[這裏](http://www.cplusplus.com/reference/cstdio/printf/)) – Michael 2015-04-04 08:59:40
@邁克爾剛剛編輯以反映嘗試使用雙打時的錯誤 – 2015-04-04 16:13:19
有關無法使用的更多詳細信息要將'float'直接傳遞給'printf',請參閱https://stackoverflow.com/questions/37082784/how-to-print-a-single-precision-float-with-printf獲取C默認參數提升規則。 – 2017-12-23 16:50:19