Day13.进入 ARM 世界: ARM Instruction Sets

学组语的目的,不见得是为了改善效能,而是:

  • 判断 optimizing compiler 产生的机械码是否正确
  • gcc 和 clang/llvm 引入大量的最佳化技术,已很难光看原始程序码,去推知最终生成的机械码
    [ARM 指令 Jserv 笔记中有提起]

在开始深入探讨前,先来看看ARM 的 Memory system

ARM Memory Systeam

  • memory 是一个 linear array of bytes addressed,范围从 0 ~ 2^32^ -1
  • 有 word, half-word, byte 三种形式
  • 采用Little Endian

Assebbler Language:Basic Syntax

label
    opcode operand1, operand2, ...; Comments
  • lable 可有可无,通常用来当作地址的标记
  • opcode 指令的操作码
  • operand 第一个operand是指令结果的destination,不同指令则有所不同个operand,例如立即数表示为 #number
MOV R0, #0x12 ; Set R0 = 0x12 (hexadecimal)
MOV R1, #'A' ; Set R1 = ASCII character A
  • Comments 为注解,使用";" 开头
  • 使用 EQU 来定义常数
NVIC_IRQ_SETEN0 EQU 0xE000E100 
NVIC_IRQ0_ENABLE EQU 0x1
  • Pseudo-instruction 是一个简单版的组语指令,没有直接等价於机器语言,在组译过程中会被翻译成一或多个机器指令
LDR R0,=NVIC_IRQ_SETEN0; ; LDR here is a pseudo-instruction that
                         ; convert to a PC relative load by
                         ; assembler.
MOV R1,#NVIC_IRQ0_ENABLE ; Move immediate data to register
STR R1,[R0]              ; Enable IRQ 0 by writing R1 to address
                         ; in R0

ARM Instruction Sets

可分成三大项:

  • Data processing
    • move
    • arithmetic
    • logical
    • comparison
    • multiply
  • Data movement (memory access)
  • Flow control

Data processing

资料处理指令包含对资料做 移动、算数、逻辑、比较、乘法 的指令

Arithmetic operations

  • ADD 指令将 Operand2 或 imm12 的值与 Rn 中的值相加。
  • ADC 指令将 Rn 和 Operand2 中的值与进位标志相加。
  • SUB 指令从 Rn 中的值中减去 Operand2 或 imm12 的值。
  • SBC 指令从 Rn 中的值中减去 Operand2 的值。 如果进位标志清零,则结果减一。
  • RSB 指令从 Operand2 的值中减去 Rn 中的值。
  • Example:
ADD    r0, r1, r2    ; r0 := r1 + r2
ADC    r0, r1, r2    ; r0 := r1 + r2 + C
SUB    r0, r1, r2    ; r0 := r1 - r2
SBC    r0, r1, r2    ; r0 := r1 - r2 + C - 1
RSB    r0, r1, r2    ; r0 := r2 - r1
RSC    r0, r1, r2    ; r0 := r2 - r1 + C - 1

Bit-wise logical operations

  • Bitwise intersection (and)
    • AND r0, r1, r2 ; r0 := r1 and r2
  • Bitwise union (or)
    • ORR r0, r1, r2 ; r0 := r1 or r2
  • Bitwise exclusive (xor)
    • EOR r0, r1, r2 ; r0 := r1 xor r2
  • Unary bitwise inverse
    • BIC r0, r1, r2 ; r0 := r1 and not r2

Register movement operations:

  • 在 register 和 register 之间移动数据
  • 在 register 和 memory 之间移动数据
  • 在 special register 和 register 之间移动数据
  • 将立即值移入 register

在ARM 的指令中加了许多条件执行的後缀

Comparison operations:

  • 大多数的ARM 的Banch指令都是根据APSR/CPSR 决定是否转移

data processing 指令可以更新 PSR

  • Example:
CMP R0, R1 ; Calculate R0 – R1 and update flag
CMP R0, #0x12 ; Calculate R0 – 0x12 and update flag
CMN R0, R1 ; Calculate R0 – (-R1) and update flag
CMN R0, #0x12 ; Calculate R0 – (-0x12) and update flag
TST R0, R1 ; Calculate R0 AND R1 and update flag
TST R0, #0x12 ; Calculate R0 AND 0x12 and update flag

Immediate operands:

  • Example:
ADD    r3, r3, #1    ; r3 := r3 + 1
AND    r8, r7, #&ff  ; r8 := r7[7:0]
  • 我们知道指令都是 32 bit 当我们想载入32-bit 该怎麽做?
load_32bit:
ldr r0, [pc #0] ;请注意: pc 位於目前位址向前 8 bytes 的地方
bx lr
.word 0xDEADBEEF
  • 在 ARMv7 後,引入两个步骤的指令来载入数值: movw, movt
movw r0, #0xbeef  ; r0 = 0x0000beef
movt r0, #0xdead ; r0 = deadbeef
  • GNU as 给予便利的写法
.equ label, 0xDEADBEEF
movw r0, #:lower16:label
movt r0, #:upper16:label

Shifted register operands:

  • Logical Shitf Right/Left 一律都是把多出来的位数填0
  • Arithmetic Shift Right 需考虑到singed的属性,假设最高是1,则填补1,反之最高是0,则填补0。
  • ROR 按值循环的Register内容的值
  • RRX 被移位指令抛出的bit被放入 C Flag中,C Flag 的值会被移入 bit[31]中。

先介绍到这 明天继续介绍剩下的指令集

参考资料

ARM指令

ARM Instruction Set

Definitive Guide To the ARM Cortex-M3


<<:  Day24-Kaggle Titanic迈进前5% part(1)

>>:  Day 13 : 基础套件的介绍-random,利用程序帮你做乱数选择

Day 2 - 如何运用sail快速建置Laravel 8.0

观看Laravel 8.0的官方文件教学,可以看到一个新的东西就是我们这次要介绍的Sail,用起来非...

ES6 常用方法

1. 语法糖 、...展开 https://codepen.io/Rouoxo/pen/ZEXXda...

Day16:今天来谈一下Microsoft Cloud App Security

Microsoft Cloud App Security是一种云端存取安全性代理人(CASB), 可...

冒险村20 - Design Pattern(1) - Decorator

20 - Design Pattern(1) - Decorator Decorator patte...