【问题标题】:Push constant directly or Mov Eax and Push Eax直接推送常量或 Mov Eax 和 Push Eax
【发布时间】:2014-08-18 04:54:53
【问题描述】:

直接push一个常量值是为了调用一个函数,而不是mov值到eax和push eax是有区别的。

例如,在 C 中执行此操作: GetStdHandle(STD_OUTPUT_HANDLE);

许多编译器都会生成这个:

;B8 F5 FF FF FF
MOV EAX,-11

;50
PUSH EAX

CALL GetStdHandle

我正在手动使用;

;6A F5
PUSH -11

CALL GetStdHandle

直接推送值而不是在eax上加载并推送eax是错误的?

【问题讨论】:

  • 没有。你在做什么就好了。

标签: assembly x86


【解决方案1】:

假设代码是 32 位模式,你应该没问题。

您可以显式指定 32 位立即数,但在 Visual Studio (2005) 汇编程序 (ML.EXE) 的情况下,它使用完整的 32 位操作数大小而不是符号扩展字节值:

; 68 F5 FF FF FF
;
        push    dword ptr -11

即使使用 Visual Studio 的汇编程序 (ML.EXE) 指定字节 ptr 也可以:

; 6A F5
;
        push    byte ptr -11

但是,使用单词 ptr 会导致 66 前缀和 16 位推送(ESP 减去 2 而不是 4):

; 66 68 F5 FF
;
        push    word ptr -11

在这种情况下,66 前缀将操作数大小(压入堆栈的值)更改为 16 位。

【讨论】:

  • 来自 Intel 的手册:“如果源操作数是立即数并且其大小小于操作数大小,则将符号扩展值压入堆栈。”。所以在实践中,他仍然在堆栈上放置一个 32 位值(假设 OP 正在构建一个 32 位可执行文件)。
  • dword ptr 真的只是覆盖立即数的宽度,而不是将其视为该绝对地址处的内存操作数? MASM 疯了。 (在 NASM 中,您将使用 push strict dword -11 表示即时,push [-11] 表示内存。)嗯,GAS .intel_syntax noprefix 类似于 MASM,并且也将其视为 push-immediate(但忽略 dword 说明符并使用字节立即数)
猜你喜欢
  • 2013-09-10
  • 2017-05-05
  • 2016-05-29
  • 2012-10-10
  • 2019-03-30
  • 2014-10-28
  • 1970-01-01
  • 1970-01-01
  • 2020-11-11
相关资源
最近更新 更多