linux-用x87 float调用printf

我在x86 asm中有一个简单的程序,它使z = x / y.关键是,除法时应正确编写代码,但不打印任何内容.没有输出.我不知道出什么问题了,因为当程序不使用eax,ebx等时,我无法调试.

global main
extern printf

section .text

    main:

    finit
    fild dword[x]
    fild dword[y]
    fdiv
    fist dword[z]

    push dword[z]
    push frm
    call printf
    add esp,8

    mov ebx,0
    mov eax,1
    int 0x80


section .data
x: dd 1.2
y: dd 3.14
z: dd 0.0
frm: dd '%lf',10,0

解决方法:

1)C库-我猜您使用的是GCC中的库-无法立即输出printf的结果.而是将其存储在称为缓存的单独内存中,并偶然输出.在这种情况下,程序将以int 0x80 /​​ eax = 1结束的速度比刷新缓存的速度快.您可以插入手动刷新:

...
extern fflush
...
push 0
call fflush
add esp, 4
...

最好的解决方案是使用C退出功能.更换

mov ebx,0
mov eax,1
int 0x80

通过

push 0
call exit

2)格式为%lf的printf需要一个双浮点数(8字节= QWORD)作为输入.因此,更改代码:

...
fstp qword[z]
...
push dword[z+4]
push dword[z]
push frm
call printf
add esp,12
...
z: dq 0.0

3)NASM将把1.2和3.14转换为浮点数.定义为dd时,它将存储为单个浮点数.但是,fild需要并加载一个整数.让它作为单个加载:

fld dword[x]
fld dword[y]

整堆:

global main
extern printf, fflush, exit

section .text

    main:

    finit
    fld dword[x]
    fld dword[y]
    fdiv
    fstp qword[z]

    push dword[z+4]
    push dword[z]
    push frm
    call printf
    add esp,12

    push 0
    call fflush
    add esp, 4

    push 0
    call exit

section .data
x: dd 1.2
y: dd 3.14
z: dq 0.0
frm: dd '%lf',10,0
上一篇:2020年最新 C# .net 面试题,月薪20K+中高级/架构师必看(10)


下一篇:linux-sys_brk的资格要求是什么