GCC 生成的 ARM 和 x86 汇编代码的差异

2024-01-23

让我们看一个简单的 C 代码来设置寄存器:

int main()
{
    int *a = (int*)111111;
    *a = 0x1000;
    return 0;
}

当我使用 1 级优化为 ARM (arm-none-eabi-gcc) 编译此代码时,汇编代码类似于:

mov     r2, #4096
mov     r3, #110592
str     r2, [r3, #519]
mov     r0, #0
bx      lr

看起来地址 111111 被解析为最近的 4K 边界 (110592) 并移动到 r3,然后通过将 519 添加到 110592 (=111111) 来存储值 4096(0x1000)。为什么会出现这种情况?

在 x86 中,汇编很简单:

movl    $4096, 111111
movl    $0, %eax
ret

这种编码背后的原因是因为 x86 具有可变大小的指令——从 1 字节到 16 字节(甚至可能带有前缀)。

ARM 指令是 32 位宽(不包括 Thumb 模式),这意味着不可能在单个操作码中对所有 32 位宽常量(立即数)进行编码。

固定大小的架构通常使用几种方法来加载大常量:

1)  movi  #r1, Imm8  ; // Here Imm8 or ImmX is simply X least significant bits
2)  movhi #r1, Imm16 ; // Here Imm16 loads the 16 MSB of the register
3)  load  #r1, (PC + ImmX);  // use PC-relative address to put constant in code
4)  movn  #r1, Imm8 ;  // load the inverse of Imm8 (for signed constants) 
5)  mov(i/n) #1, Imm8 << N;       // where N=0,8,16,24

可变大小的体系结构 OTOH 可以将所有常量放在一条指令中:

xx xx xx 00 10 00 00 11 11 11 00 ; // assuming that it takes 3 bytes to encode
                                 ; // the instruction and the addressing mode
; added with 4 bytes to encode the 4096 and 4 bytes to encode 0x00111111
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GCC 生成的 ARM 和 x86 汇编代码的差异 的相关文章

随机推荐

  • 如何更改 Eclipse 运行配置的工作目录?

    我有一个 Eclipse 运行配置 我想为其设置工作目录 我该怎么做呢 我浏览了运行配置的不同选项卡 包括 环境 选项卡 但没有看到任何明显的东西 这是开普勒 SR1 上的 参数选项卡
  • Apache CXF REST 分段上传,编码异常

    我想使用多部分表单数据上传文件 但 URLDecoder 出现问题 服务代码如下 POST Path document Consumes MediaType MULTIPART FORM DATA public Response store
  • 爆炸不适用于字符串内的多个逗号[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我尝试在这里和谷歌中找到答案 但没有
  • 如何解决 IDLE 中的 ModuleNotFound 错误?

    我使用的是ubuntu 18 04 我首先从版本为 3 7 0 的终端安装了 Python 和 anaconda 并且还启动了 Jupyter Notebook 和 Spyder 然后我安装了 IDLE 其版本为 3 6 6 并且我当前正在
  • Cython 并行 prange - 线程局部性?

    我正在使用 prange 迭代这样的列表 from cython parallel import prange threadid cdef int tid cdef CythonElement tEl cdef int a b c elLi
  • tabindex 给出了它的焦点,但是在回车键上输入它不起作用

    当我用鼠标单击搜索图标时 它工作正常 但是当我使用选项卡并且焦点转到图标时 但当我输入 ENTER 关键字时 它不起作用 div class mobile header icon i class search i div 紧迫enter不触
  • Carrierwave:如果尺寸大于则缩放图像(有条件创建版本)

    仅当图像大于版本大小时 才可以使用载波创建版本 例如拇指 吗 Example version thumb if gt is thumbnable do process resize to fit gt 32 nil end protecte
  • 类型注释被推断的表达式类型覆盖

    在 Scala 编程语言中 假设我将使用更广泛的类型注释表达式并提供一个狭窄的值 我的程序将被拒绝 scala gt def x A A 8
  • 使用 HTML 和 CSS 剪辑图像

    我想在 144px x 144px div 元素中显示图像 图像总是大于 144px 所以我想缩放它们 我的意思是最小的一侧将接触 div 的边缘 从另一侧 与信箱相反 切掉一点 我怎样才能做到这一点并让它在 IE 等旧版浏览器上也能工作
  • 在 NodeJS Lambda 函数中列出 AWS.CognitoIdentityServiceProvider.listUsers 中的用户及其组?

    因此 我需要在客户端的自定义管理屏幕中显示用户列表及其各个组 我正在返回结果AWS CognitoIdentityServiceProvider listUsers在 Lambda 函数中 这可以很好地列出用户 但我不确定为每个用户获取组并
  • 按行名称连接多个表[重复]

    这个问题在这里已经有答案了 我想按行名称合并多个表 这些表的行数不同 并且它们具有唯一行和共享行 这些行都应该出现在输出中 如果可能的话我想解决这个问题awk 但我也对其他解决方案感到满意 表1 tab a 5 b 5 d 9 表2 tab
  • C++:成员指针已初始化?

    代码示例应该解释一下 class A B pB C pC D d public A int i int j d j pC new C i abc note pB is not initialised e g pB NULL 显然 pB 应该
  • C++ 11 线程与 clang

    我想学习使用 C 11 线程来加速我的语言的编译 是的 我正在构建一个编译器 x 我尝试的第一个示例在 clang 3 3 SVN 中抛出了几个错误 它在 GCC 4 6 3 下编译得很好 我从 llvm org 的 SVN 下载了 cla
  • 将对象的子集直接解构为新对象[重复]

    这个问题在这里已经有答案了 有没有一条语句可以做到这一点 我正在空白 this state is a basic object with many keys var toDate fromDate location flavor this
  • 无法更新 FBSDKCoreKit POD iOS

    当我尝试进行 pod 更新时 出现以下错误 一旦失败 我什至无法再进行 pod install 了 安装FBSDKCoreKit 4 36 0 安装 FBSDKCoreKit 时出错 usr bin git 克隆https github c
  • Visual C++ 中的堆框架有多大

    在 Visual C 中 如果我使用 new 在堆上创建对象 堆帧头和填充会占用多少额外空间 特别是在发布代码中 我期望一个 int 表示块中有多少可用空间 另一个可能表示当前正在使用多少空间 并且帧大小根据体系结构四舍五入到最接近的 32
  • WEB API 返回遵循序列化属性的对象

    我正在使用 WEB API 返回一个对象 类 类已经使用 System Xml Serialization 属性进行结构化 这使得使用 WEB API 返回整个类变得困难 因为它公开的内容超出了应有的范围 我不认为这是序列化类并返回字符串的
  • MDX 查询返回记录数

    以下是我的 MDX 查询 SELECT NON EMPTY Measures Fact Sample Count ON COLUMNS NON EMPTY Fact Sample Sample Reference No Sample Ref
  • Django 的缓存模块可以在 Google App Engine 上运行吗?

    我正在 Google App Engine 上运行 Django 1 0 2 并且想知道以下哪一项 如果有 Django 缓存模块 http docs djangoproject com en dev topics cache 本质上应该与
  • GCC 生成的 ARM 和 x86 汇编代码的差异

    让我们看一个简单的 C 代码来设置寄存器 int main int a int 111111 a 0x1000 return 0 当我使用 1 级优化为 ARM arm none eabi gcc 编译此代码时 汇编代码类似于 mov r2