"添加esp,0FFFFFFF8h"的序幕

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)

Jos*_*hua 5

奇怪的编译器.很奇怪.

add esp, 0FFFFFFF8h
Run Code Online (Sandbox Code Playgroud)

与...完全相同

sub esp, 8h
Run Code Online (Sandbox Code Playgroud)

除了它设置标志位不同.这很好,是的,这取决于无符号整数换行.这不是问题,因为组装本质上是不可移植的.如果你想知道为什么你要问微软,他们可能不知道了.

  • @jww编译器执行此操作的一种可能性可能与需要为本地堆栈空间分配正好128个字节的情况有关.在这种情况下,`add`和`sub`之间存在差异.`add esp,-128`仍然可以用3个字节编码,但`sub esp,128`将需要6个字节.在这种情况下只需要8个字节就没关系('add`和`sub`编码为3个字节). (2认同)