首页
论坛
课程
招聘
VC++调用win32汇编DLL由于ESI寄存器使用不当导致的问题
2021-3-30 10:30 2285

VC++调用win32汇编DLL由于ESI寄存器使用不当导致的问题

2021-3-30 10:30
2285

老夫N久前用win32汇编写的一个与读卡器硬件交互的DLL供上层应用(C#)调用,上线运行一来一直相安无事。
直到昨日,该功能需要提供微型HTTP服务,老夫用C++进行调用win32汇编DLL中的一个导出函数,很简单很简单,但是·一运行,砰,嗝屁,debug下报错如图:

releas下虽不报错但得到的返回数据也会出现莫名问题,不完整,偶尔还直接驾崩,
出现这个问题无外乎想到2个原因:
1、被调用函数本身问题,函数体内出现某些异常导致堆栈平衡被破坏。
2、函数调用约定问题。
先是检查了下调用约定,也确实存在问题,我申明的是:
typedef int(FUN_xxxxxxx)(char);
这样一来VS默认的是cdecl方式,看了下当时汇编的源码是:
.model flat,stdcall
stdcall和cdecl区别这里就不多废话了╮(╯▽╰)╭;就是个由谁来扫尾的区别
随后改成typedef int(
stdcall FUN_xxxxxxx)(char);
在编译运行,卧槽·问题依旧,╮(╯▽╰)╭,当时老夫坐在办公椅上背靠着思索勒许久。
随后打开VS反汇编模式进行调试,一通调试后,最后偶然发现一个细节处
DEBUG模式下注意到有这么一句:
图片描述
比较之前保存在ESI中的原始ESP进行比较,要是不同进行CheckEsp检查就完蛋。
至此明白了,由于老夫在汇编代码中使用结构体时用了ESI寄存器
图片描述

 

随后修正如下:
图片描述
就是在使用ESI之前和之后分别加入PUSH ESI POP ESI来保存恢复ESI
至此,问题解决重新提交版本,通知更新,╮(╯▽╰)╭。
也是提醒,在汇编下使用某些特殊寄存器使用前最好还是push,pop下,以免跨语言使用出现莫名其妙的问题,╮(╯▽╰)╭


[2022冬季班]《安卓高级研修班(网课)》月薪两万班招生中~

收藏
点赞0
打赏
分享
最新回复 (4)
雪    币: 2164
活跃值: 活跃值 (1819)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
dearfuture 活跃值 2021-3-31 10:28
2
0

win的x86 abi下,esi属于非易失寄存器,编译器如果在函数用到了esi,就会在开头push结尾pop的,包括普通函数中的内联汇编都会自动添加push和pop。但如果是裸函数中的内联汇编或者masm就需要手动添加push和pop

最后于 2021-3-31 10:30 被dearfuture编辑 ,原因:
雪    币: 105
活跃值: 活跃值 (370)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xtayaitak 活跃值 2021-3-31 13:07
3
0
用汇编写应用,有什么好处吗,为什么不用C或C++
雪    币: 391
活跃值: 活跃值 (711)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
wowocock 活跃值 1 2021-3-31 14:16
4
0

几十年前大家都养成了32位下除了EAX,ECX,EDX,都保存得习惯。pushfd pushad ... popad popfd

最后于 2021-3-31 14:17 被wowocock编辑 ,原因:
雪    币: 5983
活跃值: 活跃值 (2294)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
黑洛 活跃值 1 2021-3-31 16:43
5
0
xtayaitak 用汇编写应用,有什么好处吗,为什么不用C或C++
没那么大容量,只能用汇编
游客
登录 | 注册 方可回帖
返回