如何在 i386 上将“推 2000”从 AT&T asm 转换为 Intel 语法

Posted

技术标签:

【中文标题】如何在 i386 上将“推 2000”从 AT&T asm 转换为 Intel 语法【英文标题】:How to translate "pushl 2000" from AT&T asm to Intel syntax on i386 【发布时间】:2009-11-10 18:33:23 【问题描述】:

我正在尝试将以下内容从 AT&T 程序集转换为 Intel 程序集:

pushl 2000

现在编译为:

ff 35 d0 07 00 00       pushl  0x7d0

但是无论我尝试什么,我都无法在 Intel synax 中获得相同的结果,我已经尝试过:

intel asm
disassembly after compiling to at&t

push 2000
68 d0 07 00 00          push   $0x7d0

push [2000]
68 d0 07 00 00          push   $0x7d0

push dword ptr [2000]
68 d0 07 00 00          push   $0x7d0

push dword ptr 2000
68 d0 07 00 00          push   $0x7d0

所以我没有线索,“pushl 2000”的等价物是什么?

【问题讨论】:

【参考方案1】:

我认为原始代码并没有按照您认为的那样做。根据 msdev 的反汇编是:

003AFCFC FF 35 D0 07 00 00 push        dword ptr ds:[7D0h] 

相当于推:

*((DWORD*)2000)

不将值 2000 压入堆栈。但是 - 如果这确实是您想要的,那么说明是:

push dword ptr ds:[2000]

ds: 表示使用ds 段寄存器。段寄存器是从讨厌的 16 位时代遗留下来的。主要的有cs - 代码段、ds - 数据段和ss - 堆栈段(以及fs,这是存储线程局部变量的地方)。将它们视为内存中的基本偏移量。默认情况下,数据访问不在ds 段内。

我对为什么push dword ptr [2000] 不起作用的猜测是编译器意识到这对你来说是一件愚蠢的事情并“修复了它”。通过强制使用 ds 前缀,您表明您确实打算在那里进行内存访问。

【讨论】:

这确实似乎是正确的翻译。我不能说我非常了解原始代码(我也不是很想),但我想把它翻译成 Intel 语法。你能解释一下“ds:”是从哪里来的吗? 好的 - 我在答案中添加了 ds 的一些描述。 你知道我怎么能不那么聪明吗? 对不起 - 不。我的猜测是很久以前有人在编译器中犯了一个错误,它成为了事实上的标准。【参考方案2】:

对我来说,在 GNU 汇编器 2.18 中,用于 32 位目标

.intel_syntax
push dword [2000]

生成:

0:   ff 35 d0 07 00 00       pushl  0x7d0

对于 nasm:

push dword [dword 2000]

【讨论】:

同样的代码为我生成了这个“0:68 d4 07 00 00 push $0x7d4”,因为 2.20 传递了它--32。

以上是关于如何在 i386 上将“推 2000”从 AT&T asm 转换为 Intel 语法的主要内容,如果未能解决你的问题,请参考以下文章

在 Linux 上将 MCU 设置为低功耗模式

如何在 coreOS 上将 etcd 值添加到我的 systemd 服务中?

如何在 centos 上将 dotnetcore 从 1.0.4 版本升级到 2.0.2 版本?

teamviewer 远程登录 + Ubuntu 14.04 (64bit) 安装

如何在 MACOS 上将 Java 从 9 降级到 8。 Eclipse 未与 Java 9 一起运行

如何在链接服务器上将数据从 mssql 更新到 mysql