代码之家  ›  专栏  ›  技术社区  ›  Nathan Osman

为什么这个简单的程序输出这么多字符?

  •  0
  • Nathan Osman  · 技术社区  · 14 年前

    这是我的 短的

    ; This code has been generated by the 7Basic
    ; compiler <http://launchpad.net/7basic>
    
    extern printf
    
    ; Initialized data
    
          SECTION .data
    f_0 dd 5.5
    printf_f: db "%f",10,0
    
          SECTION .text
    
    ; Code
    
    global main
      main:
    push ebp
    mov ebp,esp
    
    push dword [f_0]
    push printf_f
    call printf
    add esp,8
    
    mov esp,ebp
    pop ebp
    mov eax,0
    ret
    

    程序是什么 想象上的 要做的是打印5.5,但它打印:

    -4101885043414705786563701568963176764603483495211119243453355953219830430011006780068899468997203661787555969981250050126586203424320244681571103387315766489883301796219461838644670607029711305942610787622864198879363376953745160639821663444829839767678538571371627347101810056161000273217639447052410683392.000000

    我到底做错了什么?代码正在将这两个参数推送到 printf() 然后叫它。没什么复杂的。


    我认为我已经解决了这个问题还为时过早。我已经更新了密码。

    1 回复  |  直到 14 年前
        1
  •  5
  •   Chris Dodd    14 年前

    指令 push f_0 将f_0的地址压入堆栈,而不是内存中的5.5,因此printf例程将获取该地址,加上保存的ebp(堆栈上的下一个4字节),并将位解释为double并将其打印出来。正如你所见,这是一个非常大的数字。

    你需要从中加载8个字节 f_0 把它们推过去。像这样的

    move eax, f_0
    push dword ptr [eax+4]
    push dword ptr [eax]
    

    fld dword ptr [f_0]
    sub esp, 8
    fstp qword ptr [esp]
    

    这实际上是加载一个fp32值并将其转换为fp80(x87的内部格式),然后将该fp80值转换为fp64并存储在堆栈上。