ARM汇编学习录 2 - 编码分析

news2025/1/21 22:05:38

本文记录笔者学习对应汇编指令相关编码知识

ARM32

首先阅读基础概念:

ARM-instruction-set-encoding

A32指令全部是32位且是4字节地址对齐.

位域如下在这里插入图片描述

如何理解4字节地址对齐和指令长度?

0000139c <_start_main>:
    139c:       e92d4800        push    {fp, lr}
    13a0:       e1a0b00d        mov     fp, sp
    13a4:       e24dd010        sub     sp, sp, #16
    13a8:       e59f1030        ldr     r1, [pc, #48]   @ 13e0 <_start_main+0x44>
    13ac:       e28d3004        add     r3, sp, #4
    13b0:       e79f1001        ldr     r1, [pc, r1]
    ....

在上面展示是一个ELF中存储的函数片段。第一列是存储指令的地址(139c,13a0等),第二列为
指令编码(e92d4800等)和最后一列对应的助记符。

地址对齐:
你会发现所有的地址139c到13b0所有地址都可以被4整除(由于4字节对齐,末尾两位位域必须为0)。

指令长度

所有A32指令都是定长4字节编码。

指令位域解析

cond

cond 位域在[31,28]。 大多数ARM指令都支持条件执行.既根据APSR中N Z C V Q的条件位确定是否执行某一个指令。

APSR如下:
在这里插入图片描述
cond助记符和编码

在这里插入图片描述
举例:

0x02422010     subeq     r2, r2, #0x10
0x12422010     subne     r2, r2, #0x10

原本sub指令后面添加eq和ne后缀表示。
eq编码为0b0000 所以 subeq第一个编码为0x0
ne编码为0b0001 同理 subne第一个编码0x1

我们仔细研究subne编码如下:
在这里插入图片描述
当APSR的Z==0才会执行subne指令

op

官方 op分类表 Table 5.1
在这里插入图片描述

0x12422010     subne     r2, r2, #0x10

我们以subne举例
op1=0b001 op=0b0 所以他属于Data-processing and miscellaneous instruction.我们需要继续翻阅这个类别的文档,进一步分析格式

Data-processing and miscellaneous instruction
在这里插入图片描述

op = 1
op1 = 00100
op2 = 0001
在这里插入图片描述
从上表格可知需要查阅
Data-processing (immediate)

在这里插入图片描述
op = 00100
Rn = 0010
在这里插入图片描述
在这里插入图片描述

继续翻阅sub指令格式文档
sub(immediate,ARM)

SUB{S}<c> <Rd>, <Rn>, #<const>

在这里插入图片描述
标记位域结果:

cond = 0b0001
S = 0b0
Rn = 0b0010
RD = 0b0010
imm12 = 0b0000 0001 0000
在文档有介绍一些特殊情况如下:
#如果Rn等于 '1111' 且 S == ’0‘那么请参阅 ADR 
if Rn == '1111' && S == '0' then SEE ADR;
# 略 类似上文
if Rn == '1101' then SEE SUB (SP minus immediate);
# 略 类似上文
if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;

# 如果不是上面的特殊情况我们定义以下标志变量。

d = UInt(Rd); 
n = UInt(Rn);  
setflags = (S == '1');  
imm32 = ARMExpandImm(imm12);

Uint函数和ARMExpandImm是arm中定义伪代码函数,可参阅如下arm文档目录

在这里插入图片描述

pseudo-code 函数目录

ARMExpandImm

Uint文档

Uint函数比较简单,我们详细看看ARMExpandImm

在这里插入图片描述
标记位域结果:

cond = 0b0000
a = 0 
b = 0
c = 1
d = 0
e = 0
g = 0
h = 0

根据文档这个常量值将为0x10(cond为0的话直接根据顺序取值)

我们继续回带到sub指令中如下

d = 2
n = 2
setflags = false
imm32 = 0x10;

有这些具体变量数值后继续看sub的Operation伪代码

// ConditionPassed 根据cond和APSR判断是否能执行当前指令
if ConditionPassed() then
	//可以先忽略 排查一些未定义编码指令行为等
    EncodingSpecificOperations();
    //计算结果进位和溢出等。NOT(imm32), '1'相当于取反加1。也就是将立即数变为一个负数
    (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
    //d表示写入pc寄存器
    if d == 15 then
        ALUWritePC(result);  // setflags is always FALSE here
    else
    	//结果写入目标寄存器
        R[d] = result;
        //根据条件更新APSR
        if setflags then
            APSR.N = result<31>;
            APSR.Z = IsZeroBit(result);
            APSR.C = carry;
            APSR.V = overflow;
// AddWithCarry()
// 比较简单可自行阅读
// ==============

(bits(N), bit, bit) AddWithCarry(bits(N) x, bits(N) y, bit carry_in)
    unsigned_sum = UInt(x) + UInt(y) + UInt(carry_in);
    signed_sum   = SInt(x) + SInt(y) + UInt(carry_in);
    result       = unsigned_sum<N-1:0>;  // same value as signed_sum<N-1:0>
    carry_out    = if UInt(result) == unsigned_sum then '0' else '1';
    overflow     = if SInt(result) == signed_sum then '0' else '1';
    return (result, carry_out, overflow);

Thumb&Thumb-2

Thumb-instruction-set-encoding

我们知道thumb指令中有T1和T2两种类别,T1是16位,而T2是32位的。他们都是办字对齐(2字节对齐)

如果在Thumb运行状态下如果指令是如下开头的那么证明为thumb-2指令

0b11101
0b11110
0b11111

地址对齐概念

下图是一个实际

0000141c <main>:
    141c:       b580            push    {r7, lr}
    141e:       466f            mov     r7, sp
    1420:       f1a1 0110       sub.w   r1, r1, #16
    1424:       2200            movs    r2, #0
    1426:       9200            str     r2, [sp, #0]
    1428:       9203            str     r2, [sp, #12]
    142a:       9002            str     r0, [sp, #8]
    142c:       9101            str     r1, [sp, #4]
    142e:       9902            ldr     r1, [sp, #8]
    1430:       4803            ldr     r0, [pc, #12]   @ (1440 <main+0x24>)
    1432:       4478            add     r0, pc
    1434:       f000 e82c       blx     1490 <main+0x74>
    1438:       9800            ldr     r0, [sp, #0]
    143a:       b004            add     sp, #16
    143c:       bd80            pop     {r7, pc}
    143e:       bf00            nop
    1440:       ffffef42                        @ <UNDEFINED> instruction: 0xffffef42

第一列为地址,第二例为机器码,第三列为助记符(mnemonic)
因为thumb指令都是半字节对齐(2字节),所以第一列所有地址都可以被2整除(地址末尾为0)。

thumb指令编码示例

# 注意thumb不支持条件执行比如subeq后面的eq就支持
0x84B0(大端为0xB084)             sub  sp, #16
0x5141(大端为0x4151)             adcs r1,r2

16-bit-Thumb-instruction-encoding

另一个编码规则文档

我们以adcs举例说明

0x4151 adcs r1,r2

在这里插入图片描述

Opcode = 0b010000

通过查阅
Opcode表格得知属于数据指令,

在这里插入图片描述

Data-processing格式指令文档
在这里插入图片描述
Opcode=0b0101

Opcode表格查询得知

在这里插入图片描述

ADC指令格式

通过阅读得知编码格式如下:
在这里插入图片描述

在这里插入图片描述
ADC<c>表示在IT block的指令(thumb不像arm单独对每个指令设置条件执行,只能依靠IT指令)

具体操作如下,这里就不在做讲解

d = UInt(Rdn);  n = UInt(Rdn);  m = UInt(Rm); 
 setflags = !InITBlock();
(shift_t, shift_n) = (SRType_LSL, 0);

if ConditionPassed() then
    EncodingSpecificOperations();
    shifted = Shift(R[m], shift_t, shift_n, APSR.C);
    (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
    if d == 15 then          // Can only occur for ARM encoding
        ALUWritePC(result);  // setflags is always FALSE here
    else
        R[d] = result;
        if setflags then
            APSR.N = result<31>;
            APSR.Z = IsZeroBit(result);
            APSR.C = carry;
            APSR.V = overflow;


thumb2 指令编码示例

thumb2指令一般会带有.w后缀如 sub.w r1, r1, #16.

0xA1F11001 (大端0xF1A10110) sub.w r1, r1, #16

我们首先查阅文档可知前四位为0b11111表示32位thumb2指令
在这里插入图片描述
32-bit-Thumb-instruction-encoding

op1 = 10
op2 = 0011010
op = 0

查阅文档进行下一步分析Data-processing(modified-immediate)
在这里插入图片描述

在这里插入图片描述

op = 0b1101
S = 0b0
Rn = 0b0001
Rd = 0b0001

查阅可知是一个sub指令
在这里插入图片描述

SUB (immediate, Thumb)

SUB指令位域如下
在这里插入图片描述
助记符格式:

SUB{S}<c>.W <Rd>, <Rn>, #<const>

一些变量计算和定义

if Rd == '1111' && S == '1' then SEE CMP (immediate);
if Rn == '1101' then SEE SUB (SP minus immediate);
d = UInt(Rd);  n = UInt(Rn);  setflags = (S == '1');  imm32 = ThumbExpandImm(i:imm3:imm8);
if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;

操作定义:

if ConditionPassed() then
    EncodingSpecificOperations();
    (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
    R[d] = result;
    if setflags then
        APSR.N = result<31>;
        APSR.Z = IsZeroBit(result);
        APSR.C = carry;
        APSR.V = overflow;

ARM64

aarch64编码
Arm® Architecture Reference Manual for A-profile architecture

一个示例汇编函数:

000000000000165c <main>:
    165c:       d100c3ff        sub     sp, sp, #0x30
    1660:       a9027bfd        stp     x29, x30, [sp, #32]
    1664:       910083fd        add     x29, sp, #0x20
    1668:       2a1f03e8        mov     w8, wzr
    166c:       b9000fe8        str     w8, [sp, #12]
    1670:       b81fc3bf        stur    wzr, [x29, #-4]
    1674:       b81f83a0        stur    w0, [x29, #-8]
    1678:       f9000be1        str     x1, [sp, #16]
    167c:       b85f83a1        ldur    w1, [x29, #-8]
    1680:       f0ffffe0        adrp    x0, 0 <note_android_ident-0x2c0>
    1684:       91142000        add     x0, x0, #0x508
    1688:       94000016        bl      16e0 <printf@plt>
    168c:       b9400fe0        ldr     w0, [sp, #12]
    1690:       a9427bfd        ldp     x29, x30, [sp, #32]
    1694:       9100c3ff        add     sp, sp, #0x30
    1698:       d65f03c0        ret

我们拿出下面指令说明

0x91142000        add     x0, x0, #0x508

在这里插入图片描述

在这里插入图片描述
本例编码如下:

op1 = 1000 

可见指令属于Data Processing --Emmediate

参阅Data Processing --Emmediate指令格式如下:
在这里插入图片描述

op0 = 010 

查阅可知属于Add/substract(immediate)。参照对应文档格式如下:
在这里插入图片描述
注:
sf:标准使用32位还是64
S: 是否更新标志寄存器

本例标记如下

sf = 1
op = 0 
S = 0

根据上述变量属于Add(immediate) -64-bitr variant

继续翻阅对应文档位域视图:
在这里插入图片描述

ADD <Xd|SP>, <Xn|SP>, #<imm>{, <shift>}

具体操作类似ARM32就不在赘述。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1095125.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pyqt5-tools的安装(深度学习)

本篇主要解决上篇深度学习pyqt安装失败的问题 PyQt是一个创建GUI应用程序的工具包。它是Python编程语言和Qt库的成功融合。Qt库是最强大的库之一。PyQt是由Phil Thompson 开发。在使用labelimg对图片做标签时&#xff0c;需要用到pyqt5-tools工具&#xff0c;尝试以下下载方式&…

06在IDEA中创建Java和Web工程,了解不同工程下的类路径,在IDEA中执行Maven命令

创建Java/Web模块 类路径的概述 IDEA中普通java项目中类路径的开始就是以src目录开始的路径,编译后的字节码文件和配置文件最终都会放在out目录下 Maven生成的目录结构中src/main目录下的java和resources目录都可以看作类路径的开始,编译后的字节码文件或资源文件会放在targ…

车辆车型识别系统python+TensorFlow+Django网页界面+算法模型

一、介绍 车辆车型识别系统。本系统使用Python作为主要开发编程语言&#xff0c;通过TensorFlow搭建算法模型网络对收集到的多种车辆车型图片数据集进行训练&#xff0c;最后得到一个识别精度较高的模型文件。并基于该模型搭建Django框架的WEB网页端可视化操作界面。实现用户上…

设计模式再探——适配器模式

目录 一、背景介绍二、思路&方案三、过程1.适配器模式简介2.适配器模式的类图3.适配器模式代码4.适配器模式&#xff0c;类适配器模式和对象的对比5.适配器模式终极奥秘 四、总结五、升华 一、背景介绍 最近公司在对业务模型做构建的时候&#xff0c;涉及到和三方系统的对…

后厂村路灯:【干货分享】AppleDevelop苹果开发者到期重置

1.设备中提示&#xff1a; Before adding new devices, make sure your device list is updated for the new membership year. You have the option to remove devices from your list. 在添加新设备之前&#xff0c;请确保您的设备列表已针对新的会员年度进行了更新。您可以…

GP与LP的区别,有限责任、无限责任、无限连带责任

GP与LP的区别 GP是General Partner / 普通合伙人&#xff08;英文直译&#xff09; LP是Limited Partner / 有限合伙人&#xff08;英文直译&#xff09; GP和LP是经常出现在私募股权投资中的词汇&#xff0c;其实私募股权呢就是大家合力干一件事。很多时候&#xff0c;一个…

怎样在线修剪音频文件了?【免费,无须注册】

怎样在线修剪音频文件了&#xff1f; 推荐一个免费网址&#xff0c;且不用任何注册&#xff0c;直接可以使用 https://mp3cut.net/cn/ 上传音频文件&#xff0c; 拖动前后滚动条&#xff0c;对音频文件进行修剪。 修剪完成&#xff0c;可以保存如下格式 enjoy!! 作者简介…

[LeetCode周赛复盘] 第 115 场双周赛20231014

[LeetCode周赛复盘] 第 115 场双周赛20231014 一、本周周赛总结100095. 上一个遍历的整数1. 题目描述2. 思路分析3. 代码实现 100078. 最长相邻不相等子序列 I1. 题目描述2. 思路分析3. 代码实现 100077. 最长相邻不相等子序列 II1. 题目描述2. 思路分析3. 代码实现 100029. 和…

Premiere2024中Beat Edit插件点击没反应怎么办

今天在安装Beat Edit插件之后&#xff0c;小编遇到了一个问题&#xff0c;Beat Edit插件点击没有反应&#xff0c;该怎么解决这个问题呢&#xff1f;下面我们就来看看详细的教程。 此方法仅针对windows 用户 PR2024版本的问题 首先确定你已经安装完了插件 安装插件的方法&am…

Linux CentOS7 用户组管理

Linux操作系统基于多用户的设计理念&#xff0c;允许多个用户同时使用系统资源。用户是登录系统并使用系统资源的个体&#xff0c;其都有自己的账户和密码。用户组是将众多用户归类为一组。Linux中的用户和用户组是系统安全和权限管理的基础。本文将探讨Linux中用户组的创建和管…

word 如何编写4x4矩阵

百度上给的教程&#xff0c;打印出来没有对齐 https://jingyan.baidu.com/article/6b182309995f8dba58e159fc.html 百度上的方式试了一下&#xff0c;不会对齐。导致公式看起来很奇怪。 下面方式会自动对齐 摸索了一下发现可以用下面这种方式编写 4x4 矩阵。先创建一个 3x3…

雷电模拟器上使用第一个frida(三)简单的使用实例

经过前两篇 雷电模拟器上使用第一个frida&#xff08;一&#xff09;之安装-CSDN博客雷电模拟器上使用第一个frida&#xff08;二&#xff09;之su超级权限-CSDN博客 本篇开始记录如何使用frida进行hook。 一、先让手机模拟器端的frida server运行起来 虽然是让手机模拟器端…

简单聊一聊一种很新的DCDC电源-BOB电源

在DCDC电路中&#xff0c;除了我们熟悉的Boost Buck 以及Boost-Buck电路外&#xff0c;还存在着一个叫做Boost or Buck的电源&#xff0c;通常简称为BOB电源。 关于BOB电源&#xff0c;网上相关的介绍极少&#xff0c;小白也是在高通的电源芯片规格书中所看到了解到的。 在了…

word调整标题编号

需求 给上面的“能源站群控”编号&#xff0c;自动生成编号 3.3.1.2.3.1 步骤 第一步&#xff1a;选中“空调系统”&#xff0c;右键&#xff0c;段落&#xff0c;查看 空调系统的 大纲级别 第二步&#xff1a;选中“能源站群控”&#xff0c;右键&#xff0c;段落&#xff0…

Rust 流程控制

开发中最常见的用来控制执行流的结构是判断和循环。 判断 Rust 中的 if 表达式允许根据条件执行不同的代码分支&#xff0c;提供一个条件并表示 “如果条件满足&#xff0c;运行这段代码&#xff1b;如果条件不满足&#xff0c;不运行这段代码。” 需要注意的是&#xff0c;…

第三节:利用运行按钮运行VBA代码

《VBA之Excel应用》&#xff08;10178983&#xff09;是非常经典的&#xff0c;是我推出的第七套教程&#xff0c;定位于初级&#xff0c;目前是第一版修订。这套教程从简单的录制宏开始讲解&#xff0c;一直到窗体的搭建&#xff0c;内容丰富&#xff0c;实例众多。大家可以非…

【算法1-4】递推与递归-P1002 [NOIP2002 普及组] 过河卒

## 题目描述 棋盘上 A 点有一个过河卒&#xff0c;需要走到目标 B 点。卒行走的规则&#xff1a;可以向下、或者向右。同时在棋盘上 C 点有一个对方的马&#xff0c;该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。 棋盘用坐标表示&#…

物联网AI MicroPython传感器学习 之 TDS水质检测传感器

学物联网&#xff0c;来万物简单IoT物联网&#xff01;&#xff01; 一、产品简介 TDS是Total Dissolved Solids的缩写&#xff0c;中文名总溶解固体&#xff0c;也叫溶解性固体总量&#xff0c;他标识1升水中溶有多少毫克的可溶解性固体。一般来说&#xff0c;TDS值越高&…

CVPR 2023 | 数据驱动的解释对分布外数据具有鲁棒性吗?

论文链接&#xff1a; https://arxiv.org/abs/2303.16390 代码链接&#xff1a; https://github.com/tangli-udel/DRE 01. 研究背景&#xff1a;数据驱动的解释对分布外数据具有鲁棒性吗&#xff1f; 近年来&#xff0c;将黑盒机器学习&#xff08;ML&#xff09;模型用于高风…

1.14.C++项目:仿muduo库实现并发服务器之Util模块的设计

一、Util模块 二、实现思想 &#xff08;一&#xff09;管理 实现一些工具接口读取文件内容向文件写入内容URL编码URL解码通过HTTP状态码获取描述信息通过文件后缀名获取mime判断一个文件是不是目录判断一个文件是否是一个普通文件HTTP资源路径有效性判断 &#xff08;二&am…