首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >调用printf后汇编程序崩溃

调用printf后汇编程序崩溃
EN

Stack Overflow用户
提问于 2019-04-08 07:33:32
回答 1查看 442关注 0票数 0

我正在编写一个简单的函数来打印堆栈中的浮点值。这个函数是生成的,所以它没有被优化。程序在printf调用时崩溃。

代码语言:javascript
复制
;input: float32 as dword ptr ebp+8
printfloat32:
 push   ebp
  mov   ebp,    esp
  sub   esp,    16
;local ptr variable k at dword ptr ebp-4
  mov   dword ptr ebp-4,    lpcstr4 ;which is "%f"

movss       xmm0,           dword ptr ebp+8
cvtss2sd    xmm0,           xmm0
  sub       esp,            8
movsd       qword ptr esp,  xmm0
 push       dword ptr ebp-4
 call       printstr
  add       esp,            12

  mov   esp,    ebp
  pop   ebp
  ret

printstr是printf。下面是完整的生成代码:https://pastebin.com/g0Wff0JY

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-04-08 08:11:36

看着这张图,我发现可能是一个潜在的问题,但我不知道fasm语法:

代码语言:javascript
复制
        call    [printstr]     ;syntax used for the first call
        ...
        call    printstr       ;syntax used for the second call that fails

如果printstr是指向函数的基于内存的指针,则第二个调用语法可能试图调用存储该指针的位置,而不是通过使用内存中的值作为指向函数的指针来调用实际的函数。

在Visual Studio的最新版本中,默认的printf和scanf被有效地内联到C/C++代码中,语法相当复杂。

代码语言:javascript
复制
        includelib      legacy_stdio_definitions.lib    ;for scanf, printf, ...

我将问题中的代码转换为masm语法,将printstr更改为printf,并在64位Windows 7专业版上使用Visual Studio 2015测试了32位构建(构建是32位,因此在32位模式下运行)。我对这段代码没有任何问题。我怀疑问题出在不带括号的对printstr的第二次调用中,我将其更正为masm语法转换的一部分。

代码语言:javascript
复制
        .data
varf    real4   123.75
lpcstr4 db      "%f",00ah,0             ;added new line
        .code
        extern  printf:near             ;instead of printstr

printfloat32 proc
        push    ebp
        mov     ebp,esp
        sub     esp,16
        mov     dword ptr [ebp-4], offset lpcstr4
        movss   xmm0,dword ptr [ebp+8]
        cvtss2sd xmm0,xmm0
        sub     esp,8
        movsd   qword ptr [esp],xmm0
        push    dword ptr [ebp-4]
        call    printf                  ;was printstr
        add     esp,12
        mov     esp,ebp
        pop     ebp
        ret
printfloat32 endp

main    proc
        push    varf            ;test printfloat32 function
        call    printfloat32
        add     esp,4
        xor     eax,eax
        ret
main    endp
        end

使用printstr作为指向printf的指针。Masm不需要括号,因为它知道printstr是dd (指向printf的指针)。

代码语言:javascript
复制
        .code
        extern  printf:near
printstr dd     printf          ;masm doesn't need brackets

printfloat32 proc
;       ...
        call    printstr        ;masm doesn't need brackets
;       ...
printfloat32 endp

如果printstr位于此源文件的外部,则masm语法将为

代码语言:javascript
复制
        extrn   printstr:ptr    ; or extern   printstr:dword
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55564584

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档