c - 调用 printf 后汇编程序崩溃
问题描述
我正在编写一个简单的函数来从堆栈中打印一个浮点值。这个函数是生成的,所以没有优化。程序在 printf 调用时崩溃。
;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
解决方案
查看图像,我看到可能是一个潜在问题,但我不知道 fasm 语法:
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++ 代码中,语法相当复杂。而不是处理这个,有可用的可调用旧版本需要这个 includelib 语句:
includelib legacy_stdio_definitions.lib ;for scanf, printf, ...
我将代码从问题转换为 masm 语法,将 printstr 更改为 printf 并在 Windows 7 Pro 64 位上使用 Visual Studio 2015 测试了 32 位构建(构建是 32 位,因此在 32 位模式下运行)。我对这段代码没有任何问题。我使用调试器单步执行了代码,并没有发现堆栈中的存储方式有任何问题。我怀疑问题出在不带括号的第二次 printstr 调用中,我在转换为 masm 语法时对其进行了更正。
.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 的指针)。
.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 语法为
extrn printstr:ptr ; or extern printstr:dword
推荐阅读
- reactjs - 如何在 React 的 package.json 中添加多个代理?
- javascript - 切换标签时反应倒计时循环计时器重置
- javascript - For循环在javascript中初始化新实例
- python - 有没有一种方法可以暂停一个函数但不影响 Python 中的其他函数?
- actions-on-google - Google Assistant - 数据存储(对话历史)
- python - 如何使用python中的docx或python-docx包将多个绘图图保存在一个文档文件中
- database - MongoDb,克隆数据库错误:非法参数组合:无法指定 --db 和 --uri
- mysql - MySql 8 连接一个字符串
- django - 为什么 django TestCase 不创建测试数据库?
- python - Xpath 选择只返回第一个响应结果