【杂谈2】
汇编中的shadow space是啥?
[2023-11-22/20:33]
一开始只是学了汇编,用的是Paul A. Carter的教材《PC Assembly Language》。但是他书里的代码好像是32为电脑时代的东西了,甚至不能在Windows桌面操作系统上跑。
我用的nasm + mingw gcc。看作者还在官网里回答过别人的问题,能不能用nasm、mingw这个组合跑书里的代码,作者说可以,只要小改一下就可以了。
结果是,我改完之后,如果用nasm -m64
来汇编,汇编器就告诉我这些代码与64位机器不兼容,如果用-m32
来汇编,就会出现什么not found信息我也忘了,两头跑不通,我那时查了一整天没找到解决方法,只能是放弃。
然后我就寻思着,那就不用他的代码了呗,自己写不行吗。一开始还想找纯汇编的,但发现资料很少。又换个思路,在汇编里调用C函数,比如printf什么的。
无语的是,一个正常的汇编程序,被一个正常的C程序调用,竟然出错了!
X86_64 assembly: relocated truncated to fit: IMAGE_REL_AMD64_ADDR32 against '.data'
应该就是这个傻逼报错,把我整吐了。
又是各种搜。
直到搜到了这个里的solution3。当时还不知道什么是calling convention,只是拿着它的代码一顿编译汇编运行,结果成功了!
于是也开始好奇这个所谓的shadow space是个啥。
大概意思是微软x64的汇编调用约定(calling convention)中在调用函数之前需要开辟出32bytes的栈空间,然后再执行call
调用函数。
而这个32bytes的空间好像是为了调试方便才开辟出来的,好像是说优化的编译不会出现这个玩意儿。
但看不懂啊,特别是那篇文章,有一种chatgpt写出来的质感,而问答那篇说得又很简洁,我只能再搜了。
然后搜到这个GitHub上的汇编学习笔记,感觉挺有戏,等下再看看。
[2023-11-22/22:14]
傻逼的事情发生了,去看了上面说的学习笔记,里面确实提到了shadow space,但我拿着之前运行成功的那个汇编代码,把里面的shadow space的指令注释掉了……然后……运行仍然成功。
我突然想起来我当时好像还没有看到函数调用这一节就急着去跑汇编了,所以问题的真正所在可能是……我当时写的汇编函数没有prolog和epilog……