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

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

ARM32

首先阅读基础概念:

ARM-instruction-set-encoding

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

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

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

0000139c <_start_main>:139c:       e92d4800        push    {fp, lr}13a0:       e1a0b00d        mov     fp, sp13a4:       e24dd010        sub     sp, sp, #1613a8:       e59f1030        ldr     r1, [pc, #48]   @ 13e0 <_start_main+0x44>13ac:       e28d3004        add     r3, sp, #413b0:       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 thenALUWritePC(result);  // setflags is always FALSE hereelse//结果写入目标寄存器R[d] = result;//根据条件更新APSRif setflags thenAPSR.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, sp1420:       f1a1 0110       sub.w   r1, r1, #161424:       2200            movs    r2, #01426:       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, pc1434:       f000 e82c       blx     1490 <main+0x74>1438:       9800            ldr     r0, [sp, #0]143a:       b004            add     sp, #16143c:       bd80            pop     {r7, pc}143e:       bf00            nop1440:       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() thenEncodingSpecificOperations();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 encodingALUWritePC(result);  // setflags is always FALSE hereelseR[d] = result;if setflags thenAPSR.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() thenEncodingSpecificOperations();(result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');R[d] = result;if setflags thenAPSR.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, #0x301660:       a9027bfd        stp     x29, x30, [sp, #32]1664:       910083fd        add     x29, sp, #0x201668:       2a1f03e8        mov     w8, wzr166c:       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, #0x5081688:       94000016        bl      16e0 <printf@plt>168c:       b9400fe0        ldr     w0, [sp, #12]1690:       a9427bfd        ldp     x29, x30, [sp, #32]1694:       9100c3ff        add     sp, sp, #0x301698:       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.rhkb.cn/news/159365.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Docker】Harbor私有仓库与管理

搭建本地私有仓库 #首先下载 registry 镜像 docker pull registry#在 daemon.json 文件中添加私有镜像仓库地址 vim /etc/docker/daemon.json {"insecure-registries": ["192.168.220.101:5000"], #添加&#xff0c;注意用逗号结尾"registry-mi…

网络基础2(1)

HTTP 1.应用层协议2.send和recv单独使用不安全3.URL4.urlencode和urldecode5.HTTP协议格式6.HTTP中的常见请求方法POST&&GET7.HTTP的状态码8.HTTP常见Header &#x1f31f;&#x1f31f;hello&#xff0c;各位读者大大们你们好呀&#x1f31f;&#x1f31f; &#x1f6…

Git Commit Message规范

概述 Git commit message规范是一种良好的实践&#xff0c;可以帮助开发团队更好地理解和维护代码库的历史记录。它可以提高代码质量、可读性和可维护性。下面是一种常见的Git commit message规范&#xff0c;通常被称为"Conventional Commits"规范&#xff1a; 一…

Zabbix 使用同一ODBC监控不同版本MySQL

一、ODBC介绍 ODBC是Open Database Connect 即开发数据库互连的简称&#xff0c;它是一个用于访问数据库的统一界面标准。ODBC引入一个公共接口以解决不同数据库潜在的不一致性&#xff0c;从而很好的保证了基于数据库系统的应用程序的相对独立性。ODBC 概念由 Microsoft 开发&…

C++指针解读(3)-- 指针变量作为函数参数

函数执行是通过系统栈来实现的&#xff0c;系统栈分为若干个栈帧。栈帧就是函数运行的环境&#xff0c;每个函数在被调用时都会在系统栈区形成一个叫栈帧的结构。一次函数调用相关的数据保存在栈帧中&#xff0c;比如函数参数、函数的局部变量、函数执行完后的返回地址等数据。…

嵌入式C语言自我修养《GNU C编译器扩展语法》学习笔记

目录 一、C语言标准和编译器 二、指定初始化 三、宏构造“利器”&#xff1a;语句表达式 四、typeof与container_of宏 五、零长度数组 六、属性声明&#xff1a;section 七、属性声明&#xff1a;aligned 一、C语言标准和编译器 C语言标准的发展过程&#xff1a; ●…

机器学习笔记 - 使用3D卷积神经网络进行视频分类

1、导入相应的库 3D CNN 使用三维滤波器来执行卷积。内核能够在三个方向上滑动,而在 2D CNN 中它可以在二维上滑动。 首先安装并导入必要的库,用于处理ZIP文件内容的Remotezip 、用于使用进度条的tqdm 、用于处理视频文件的OpenCV 、用于执行更复杂的张量操作的einop…

flink教程

文章目录 来自于尚硅谷教程1. Flink概述1.1 特点1.2 与SparkStreaming对比 2. Flink部署2.1 集群角色2.2 部署模式2.3 Standalone运行模式2.3.1 本地会话模式部署2.3.2 应用模式 2.4 YARN运行模式2.4.1 会话模式部署2.4.2 应用模式部署 2.5 历史服务 3. 系统架构3.1 并行度3.2 …

Android 内存治理之线程

1、 前言 当我们在应用程序中启动一个线程的时候&#xff0c;也是有可能发生OOM错误的。当我们看到以下log的时候&#xff0c;就说明系统分配线程栈失败了。 java.lang.OutOfMemoryError: pthread_create (1040KB stack) failed: Out of memory这种情况可能是两种原因导致的。…

springcloud笔记(7)-限流降级Sentinel

官方文档&#xff1a;概述 | Spring Cloud Alibaba basic-api-resource-rule | Sentinel (sentinelguard.io) Sentinel是SpringCloudAlibaba的组件。 sentinel的功能 introduction | Sentinel 流量控制 熔断降级&#xff1a;降低调用链路中的不稳定资源 系统负载保护&am…

Stirling-PDF:一款优秀的开源PDF处理工具

最近我的朋友大雄需要将一个PDF转换为Word文档。于是他在网上尝试了多个PDF转换的在线工具&#xff0c;但要么需要会员&#xff0c;要么需要登录等繁琐操作&#xff0c;而且我们的文件也存在泄漏等安全隐患。因此&#xff0c;他向我咨询是否有可私有化部署且易于使用的PDF在线工…

orgChart.js组织架构图

OrgChart.js是什么&#xff1f; 基于ES6的组织结构图插件。 特征 支持本地数据和远程数据&#xff08;JSON&#xff09;。 基于CSS3过渡的平滑扩展/折叠效果。 将图表对齐为4个方向。 允许用户通过拖放节点更改组织结构。 允许用户动态编辑组织图并将最终层次结构保存为…

C# OpenVINO 人脸识别

效果 耗时 Preprocess: 1.41ms Infer: 4.38ms Postprocess: 0.03ms Total: 5.82ms 项目 代码 using OpenCvSharp; using Sdcb.OpenVINO; using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Text; using Syste…

爬虫 | 正则、Xpath、BeautifulSoup示例学习

文章目录 &#x1f4da;import requests&#x1f4da;import re&#x1f4da;from lxml import etree&#x1f4da;from bs4 import BeautifulSoup&#x1f4da;小结 契机是课程项目需要爬取一份数据&#xff0c;于是在CSDN搜了搜相关的教程。在博主【朦胧的雨梦】主页学到很多…

EfficientDet: Scalable and Efficient Object Detection

CVPR2020 V7 Mon, 27 Jul 2020 引用量&#xff1a;243 机构&#xff1a;Google 贡献&#xff1a;1>提出了多尺度融合网络BiFPN 2>对backbone、feature network、box/class prediction network and resolution进行复合放缩&#xff0c;有着不同的…

Vmware Linux虚拟机安装教程(Centos版)

文章目录 1.Vmware-workstation安装软件2.双击下载的安装包开始安装3.打开VMware-workstation&#xff0c;输入密钥4.Centos7.6安装软件5.新建虚拟机6.为虚拟机配置映像文件7.开启虚拟机&#xff0c;配置环境7.1 Install Centos 77.2 选择简体中文字体7.3 软件选择7.4 安装位置…

Python 字典

目录 1 字典介绍2 字典的创建3 字典元素的访问4 字典元素添加、修改、删除5 序列解包6 表格数据使用字典和列表存储&#xff0c;并实现访问7 字典核心底层原理(重要)7.1 将一个键值对放进字典的底层过程7.2 扩容7.3 根据键查找“键值对”的底层过程7.4 用法总结&#xff1a; 声…

Linux 系统安装 Redis7 —— 超详细操作演示!

内存数据库 Redis7 一、Redis 概述1.1 Redis 简介1.2 Redis 的用途1.3 Redis 特性1.4 Redis 的IO模型 二、Redis 的安装与配置2.1 Redis 的安装2.2 连接前的配置2.3 Redis 客户端分类2.4 Redis 配置文件详解 三、Redis 命令四、Redis 持久化五、Redis 主从集群六、Redis 分布式…

【C++基础】10. 指针

文章目录 【 1. 指针的定义 】【 2. 指针的调用 】【 3. NULL 空指针 】【 4. 指针的算术运算 】4.1 指针的递加4.2 指针的递减4.3 指针的比较 【 5. 指针与数组 】5.1 通过指针操作数组5.2 指针数组、数组指针 【 6. 指向指针的指针(多级间接寻址)】【 7. 传递指针给函数 】【…

B树、B+树详解

B树 前言   首先&#xff0c;为什么要总结B树、B树的知识呢&#xff1f;最近在学习数据库索引调优相关知识&#xff0c;数据库系统普遍采用B-/Tree作为索引结构&#xff08;例如mysql的InnoDB引擎使用的B树&#xff09;&#xff0c;理解不透彻B树&#xff0c;则无法理解数据…