如何在 GCC x86 内联汇编中使用地址常量

2024-01-08

GCC 工具链默认使用 AT&T 汇编器语法,但可以通过以下方式获得对 Intel 语法的支持.intel_syntax指示。

此外,AT&T 和 Intel 语法都可以在prefix and a noprefix版本,不同之处在于是否需要在寄存器名称前加上前缀% sigil.

根据存在的指令,地址常量的格式会发生变化。

让我们考虑以下 C 代码

*(int *)0xdeadbeef = 0x1234;

Using objdump -d,我们发现它被编译为以下汇编指令

movl $0x1234,0xdeadbeef

由于不涉及寄存器,因此这是两者的正确语法.att_syntax prefix and .att_syntax noprefix, IE。嵌入到C代码中,它们看起来像这样

__asm__(".att_syntax prefix");
__asm__("movl $0x1234,0xdeadbeef");

__asm__(".att_syntax noprefix");
__asm__("movl $0x1234,0xdeadbeef");

您可以选择用括号将地址常量括起来,即。

__asm__("movl $0x1234,(0xdeadbeef)");

也会起作用。

当向普通地址常量添加印记时,代码将无法编译

__asm__("movl $0x1234,$0xdeadbeef"); // won't compile

当用括号括住该表达式时,编译器将在没有警告的情况下发出错误代码,即

__asm__("movl $0x1234,($0xdeadbeef)"); // doesn't warn, but doesn't work!

这将错误地发出指令

movl $0x1234,0x0

在 Intel 模式下,地址常量必须以段寄存器以及操作数大小和PTR标记是否可能存在歧义。在我的机器(装有 Windows XP 和当前 MinGW 和 Cygwin GCC 版本的 Intel 双核笔记本电脑)上,寄存器ds默认使用。

常量两边的方括号是可选的。如果省略段寄存器,但存在括号,则也可以正确识别地址常量。不过,省略寄存器会在我的系统上发出警告。

In prefix模式下,段寄存器必须以前缀%,但仅使用括号仍然有效。以下是生成正确指令的不同方法:

__asm__(".intel_syntax noprefix");
__asm__("mov DWORD PTR ds:0xdeadbeef,0x1234");
__asm__("mov DWORD PTR ds:[0xdeadbeef],0x1234");
__asm__("mov DWORD PTR [0xdeadbeef],0x1234"); // works, but warns!

__asm__(".intel_syntax prefix");
__asm__("mov DWORD PTR %ds:0xdeadbeef,0x1234");
__asm__("mov DWORD PTR %ds:[0xdeadbeef],0x1234");
__asm__("mov DWORD PTR [0xdeadbeef],0x1234"); // works, but warns!

省略段寄存器和括号将无法编译

__asm__("mov DWORD PTR 0xdeadbeef,0x1234"); // won't compile

我将这个问题标记为社区维基,因此,如果您有任何有用的内容需要添加,请随时添加。


The noprefix/prefix指令仅控制寄存器是否需要%prefix(*) (至少看起来是这样,这是文档提到的唯一区别)。值文字总是需要一个$AT&T 语法中的前缀,Intel 语法中的前缀。所以以下工作:

__asm__(".intel_syntax prefix");
__asm__("MOV [DWORD PTR 0xDEADBEEF], 0x1234");

如果您确实倾向于在使用 GCC 编译并使用 GAS 汇编的 C 代码中使用 Intel 语法内联汇编,请不要忘记在其后面添加以下内容,以便汇编器可以理解由生成的(AT&T 语法)汇编的其余部分海湾合作委员会:

__asm__(".att_syntax prefix");

我认为前缀/无前缀区别的原因是,对于 AT&T 语法,%Intel 架构上的寄存器实际上并不需要前缀,因为寄存器是有名称的。但为了统一起见,它可以在那里,因为一些其他体系结构(即 SPARC)已经对编号进行了注册,在这种情况下,单独指定一个低编号会导致内存地址或寄存器的含义不明确。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 GCC x86 内联汇编中使用地址常量 的相关文章

  • 注销租约抛出 InvalidOperationException

    我有一个使用插件的应用程序 我在另一个应用程序域中加载插件 我使用 RemoteHandle 类http www pocketsilicon com post Things That Make My Life Hell Part 1 App
  • 在 DataView 的 RowFilter 中选择 DISTINCT

    我试图根据与另一个表的关系缩小 DataView 中的行范围 我使用的 RowFilter 如下 dv new DataView myDS myTable id IN SELECT DISTINCT parentID FROM myOthe
  • 复制 std::function 的成本有多高?

    While std function是可移动的 但在某些情况下不可能或不方便 复制它会受到重大处罚吗 它是否可能取决于捕获变量的大小 如果它是使用 lambda 表达式创建的 它依赖于实现吗 std function通常被实现为值语义 小缓
  • 为什么极端下派生类(多重虚拟继承)的大小包括超类成员大小的两倍?

    include
  • 复制目录内容

    我想将目录 tmp1 的内容复制到另一个目录 tmp2 tmp1 可能包含文件和其他目录 我想使用C C 复制tmp1的内容 包括模式 如果 tmp1 包含目录树 我想递归复制它们 最简单的解决方案是什么 我找到了一个解决方案来打开目录并读
  • 如何创建包含 IPv4 地址的文本框? [复制]

    这个问题在这里已经有答案了 如何制作一个这样的文本框 我想所有的用户都见过这个并且知道它的功能 您可以使用带有 Mask 的 MaskedTestBox000 000 000 000 欲了解更多信息 请参阅文档 http msdn micr
  • 使用8086汇编语言画圆[关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我试图使用 8086 汇编器画一个圆 我尝试利用中点圆算法 https en wikipedia org wiki Midpoin
  • 具有交替类型的可变参数模板参数包

    我想知道是否可以使用参数包捕获交替参数模式 例如 template
  • 我可以使用 moq Mock 来模拟类而不是接口吗?

    正在经历https github com Moq moq4 wiki Quickstart https github com Moq moq4 wiki Quickstart 我看到它 Mock 一个接口 我的遗留代码中有一个没有接口的类
  • x86-64 AMD 上 CALL 指令的操作数生成

    以下是示例程序 objdump 的输出 080483b4
  • C# 中的合并运算符?

    我想我记得看到过类似的东西 三元运算符 http msdn microsoft com en us library ty67wk28 28VS 80 29 aspx在 C 中 它只有两部分 如果变量值不为空 则返回变量值 如果为空 则返回默
  • 为什么 std::strstream 被弃用?

    我最近发现std strstream已被弃用 取而代之的是std stringstream 我已经有一段时间没有使用它了 但它做了我当时需要做的事情 所以很惊讶听到它的弃用 我的问题是为什么做出这个决定 有什么好处std stringstr
  • AES 128 CBC 蒙特卡罗测试

    我正在 AES 128 CBC 上执行 MCT 如中所述http csrc nist gov groups STM cavp documents aes AESAVS pdf http csrc nist gov groups STM ca
  • “接口”类似于 boost::bind 的语义

    我希望能够将 Java 的接口语义与 C 结合起来 起初 我用过boost signal为给定事件回调显式注册的成员函数 这非常有效 但后来我发现一些函数回调池是相关的 因此将它们抽象出来并立即注册所有实例的相关回调是有意义的 但我了解到的
  • Cmake 链接共享库:包含库中的头文件时“没有这样的文件或目录”

    我正在学习使用 CMake 构建库 构建库的代码结构如下 include Test hpp ITest hpp interface src Test cpp ITest cpp 在 CMakeLists txt 中 我用来构建库的句子是 f
  • C++ 函数重载类似转换

    我收到一个错误 指出两个重载具有相似的转换 我尝试了太多的事情 但没有任何帮助 这是那段代码 CString GetInput int numberOfInput BOOL clearBuffer FALSE UINT timeout IN
  • 不同类型指针之间的减法[重复]

    这个问题在这里已经有答案了 我试图找到两个变量之间的内存距离 具体来说 我需要找到 char 数组和 int 之间的距离 char data 5 int a 0 printf p n p n data 5 a long int distan
  • 方法优化 - C#

    我开发了一种方法 允许我通过参数传入表 字符串 列数组 字符串 和值数组 对象 然后使用这些参数创建参数化查询 虽然它工作得很好 但代码的长度以及多个 for 循环散发出一种代码味道 特别是我觉得我用来在列和值之间插入逗号的方法可以用不同的
  • C++ 条件编译

    我有以下代码片段 ifdef DO LOG define log p record p else define log p endif void record char data 现在如果我打电话log hello world 在我的代码中
  • 如何从 ODBC 连接获取可用表的列表?

    在 Excel 中 我可以转到 数据 gt 导入外部数据 gt 导入数据 然后选择要使用的数据源 然后在提供登录信息后 它会给我一个表格列表 我想知道如何使用 C 以编程方式获取该列表 您正在查询什么类型的数据源 SQL 服务器 使用权 看

随机推荐