jww*_*jww 3 x86 assembly masm integer-overflow stack-pointer
我的MASM上有点生疏,所以我真的不记得在这里做什么(如果有什么需要做的话).我有一个MASM(X86)例程,如下所示.它有两个局部变量,共占用5个字节:
MSC_ASM_GenerateBlock PROC buffer:DWORD,bsize:DWORD,safety:DWORD
LOCAL val:DWORD, rc:BYTE ;; local variables
MWSIZE EQU 4 ;; machine word size
.WHILE bsize >= MWSIZE && safety > 0
;; RDRAND is not available prior to VS2012. Just emit
;; the byte codes using DB. This is `rdrand eax`.
DB 0Fh, 0C7h, 0F0h
setc rc
...
.ENDW
...
MSC_ASM_GenerateBlock ENDP
Run Code Online (Sandbox Code Playgroud)
当我检查拆卸时,我看到:
> dumpbin.exe /DISASM rdrand-x86.obj
Dump of file rdrand-x86.obj
_MSC_ASM_GenerateBlock:
00000000: 55 push ebp
00000001: 8B EC mov ebp,esp
00000003: 83 C4 F8 add esp,0FFFFFFF8h
00000006: EB 1D jmp 00000025
00000008: 0F C7 F0 rdrand eax
0000000B: 0F 92 45 FB setb byte ptr [ebp-5]
0000000F: 80 7D FB 00 cmp byte ptr [ebp-5],0
...
Run Code Online (Sandbox Code Playgroud)
我相信add esp, 0FFFFFFF8h是另一种说法sub esp, 08h.
正如约书亚所指出的,一个add esp和之间的区别sub esp是操作后的标志.汇编程序的混淆或指令选择可以基于汇编程序无法查看RDRAND上下文的事实.相反,它只看到jmp基于CY,并且汇编程序认为标志不是很好的状态.
为什么MASM生成非直观的add依赖于无符号整数换行?更重要的是,它可以吗?
我使用更宽的机器字执行了到MASM64/ML64的路由端口.它产生相同的代码(模数机器字大小):
Dump of file rdrand-x64.obj
MSC_ASM_GenerateBlock:
0000000000000000: 55 push rbp
0000000000000001: 48 8B EC mov rbp,rsp
0000000000000004: 48 83 C4 F0 add rsp,0FFFFFFFFFFFFFFF0h
0000000000000008: EB 1D jmp 0000000000000037
0000000000000010: 48 0F C7 F0 rdrand rax
000000000000001D: 0F 92 45 F7 setb byte ptr [rbp-9]
0000000000000024: 80 7D F7 00 cmp byte ptr [rbp-9],0
...
Run Code Online (Sandbox Code Playgroud)
奇怪的编译器.很奇怪.
add esp, 0FFFFFFF8h
Run Code Online (Sandbox Code Playgroud)
与...完全相同
sub esp, 8h
Run Code Online (Sandbox Code Playgroud)
除了它设置标志位不同.这很好,是的,这取决于无符号整数换行.这不是问题,因为组装本质上是不可移植的.如果你想知道为什么你要问微软,他们可能不知道了.