获取汇编指令的编码字节长度

皓哥笔直的背影,就是我前进的方向。(——想说这句话真的好久了)


最近在皓哥的激励下也在慢慢啃CSAPP,今天看到第三章程序的机器级表示,里面有一道习题3.11是这样的:

常常可以看见以下形式的汇编代码行:
xorq %rdx, %rdx
但是在产生这段汇编代码的C代码中,并没有出现EXCLLUSIVE-OR操作
A. 解释这条特殊的EXCLUSIVE-OR指令的效果,它实现了什么有用的操作
B. 更直接地表达这个操作的汇编代码是什么?
C. 比较同样一个操作的两种不同实现的编码字节长度

前两问都比较简单,这就是利用异或将某个寄存器置0的指令,但是第三问直接看懵了,完全没有印象指令的字节长度怎么求,看答案答案也只说xorq是3字节,movq是7字节,怎么来的也没讲,于是去网上搜索了一下,找到一个别人的提问,我也照着自己做了一下

  1. 编写相应的汇编代码
    汇编代码
  2. 对其进行汇编
    as -o test.o test.c
  3. 查看其中的字节
    nm test.o
    结果

可以看到,xorq指令占用0-2共3个字节,movq指令占用 3-9共7个字节。不过具体是如何计算的,我也暂时还没有很明白,欢迎大佬们赐教

### ARM汇编指令长度规则详解 ARM架构中的汇编指令长度主要取决于其指令集的设计特点以及具体的实现方式。以下是关于ARM汇编指令长度的相关规则: #### 1. 指令宽度 在经典ARM架构中,每条指令的宽度固定为 **32位 (4字节)**[^1]。这意味着无论是一条简单的 `MOV` 指令还是一条复杂的算术运算指令,它们都占用相同的存储空间。 对于Thumb状态下的指令集(一种用于节省代码空间的状态),指令宽度通常为 **16位 (2字节)** 或者扩展到 **32位** 的 Thumb-2 模式下[^2]。这种模式允许更紧凑的代码表示形式,在资源受限的情况下非常有用。 #### 2. 地址对齐要求 由于标准ARM指令总是32位宽,因此所有的指令地址都需要按照 **4字节边界对齐** 来放置。如果违反此规则,则可能导致不可预测的行为或者硬件错误。 而在Thumb状态下,因为大多数情况下单条指令只有16位大小,所以只需要满足 **2字节边界对齐** 即可。 #### 3. 数据传输与操作数影响 尽管基本指令本身具有固定的长度,但是当涉及到立即数(immediate value)或者其他复杂参数时,可能会通过编码技巧来调整实际表现效果而不改变整体指令尺寸。例如某些特定范围内的数值可以直接嵌入到当前指令内部作为附加信息;超出该范围的情况可能需要额外加载寄存器完成相应功能[^3]。 下面展示了一个简单例子说明不同类型的mov指令及其对应的机器码长度: ```assembly ; 将常量0x1F赋给R0, 此处可以用单一指令表达 MOV R0,#0x1F ; 对应于一条完整的32-bit instruction ; 如果尝试移动更大的值比如0xFFFF至目标寄存器,则需分解成两条命令序列 LDR R1,=0xFFFF ; 这里实际上是先预留位置并稍后填充具体地址 ; 它实际上会产生多条连续但逻辑关联紧密的小型子指令组合而成的结果 ``` 综上所述,虽然传统意义上的纯ARM指令保持恒定不变的标准单位——即四个八进制字符构成的整体结构体(亦即是说每一个单独存在的动作均占据整整四格的空间),然而随着技术发展进步出现了更多灵活变通的选择方案可供选用以适应多样化需求场景之中去达成最佳性能指标平衡点所在之处。 ---
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值