鸿蒙内核源码分析 (编码方式篇) | 机器指令是如何编码的?

本篇说清楚 ARM指令是如何被编码的,机器指令由哪些部分构成,指令有哪些类型,每种类型的语法又是怎样的 ?

代码案例 | C -> 汇编 -> 机器指令

看一段C语言编译(clang)成的最后的机器指令(armv7)

int main(){
    int a = 0;
    if( a != 1) 
        a = 2*a + 1;
    return a;
}

生成汇编代码如下:

    main:
60c: sub	sp, sp, #8
610: mov	r0, #0
614: str	r0, [sp, #4]
618: str	r0, [sp]
61c: ldr	r0, [sp]
620: cmp	r0, #1
624: beq	640 <main+0x34>
628: b	62c <main+0x20>
62c: ldr	r1, [sp]
630: mov	r0, #1
634: orr	r0, r0, r1, lsl #1
638: str	r0, [sp]
63c: b	640 <main+0x34>
640: ldr	r0, [sp]
644: add	sp, sp, #8
648: bx	lr

汇编代码对应的机器指令如下图所示:

便于后续分析,将以上代码整理成如下表格

汇编代码 机器指令(十六进制表示) 机器指令(二进制表示)
sub sp, sp, #8 e24dd008 1110 0010 0100 1101 1101 0000 0000 1000
mov r0, #0 e3a00000 1110 0011 1010 0000 0000 0000 0000 0000
str r0, [sp, #4] e58d0004 1110 0101 1000 1101 0000 0000 0000 0100
str r0, [sp] e58d0000 1110 0101 1000 1101 0000 0000 0000 0000
ldr r0, [sp] e59d0000 1110 0101 1001 1101 0000 0000 0000 0000
cmp r0, #1 e3500001 1110 0011 0101 0000 0000 0000 0000 0001
beq 640 <main+0x34> 0a000005 0000 1010 0000 0000 0000 0000 0000 0101
b 62c <main+0x20> eaffffff 1110 1010 1111 1111 1111 1111 1111 1111
ldr r1, [sp] e59d1000 1110 0101 1001 1101 0001 0000 0000 0010
mov r0, #1 e3a00002 1110 0011 1010 0000 0000 0000 0000 0001
orr r0, r0, r1, lsl #1 e1800081 1110 0001 1000 0000 0000 0000 1000 0001
str r0, [sp] e58d0000 1110 0101 1000 1101 0000 0000 0000 0000
b 640 <main+0x34> eaffffff 1110 1010 1111 1111 1111 1111 1111 1111
ldr r0, [sp] e59d1000 1110 0101 1001 1101 0001 0000 0000 0000
add sp, sp, #8 e28dd008 1110 0010 1000 1101 1101 0000 0000 1000
bx lr e12fff1e 1110 0001 0010 1111 1111 1111 0001 1110

CPSR寄存器

在理解本篇之前需了解下CPSR寄存器的高4[31,28] 表达的含义。关于寄存器的详细介绍可翻看 系列篇的 (寄存器篇)

N、Z、C、V均为条件码标志位。它们的内容可被算术或逻辑运算的结果所改变,并且可以决定某条指令是否被执行!意义重大!

  • CPSR的第31位是 N,符号标志位。它记录相关指令执行后,其结果是否为负。
    如果为负 N = 1,如果是非负数 N = 0
  • CPSR的第30位是Z0标志位。它记录相关指令执行后,其结果是否为0
    如果结果为0。那么Z = 1。如果结果不为0,那么Z = 0
  • CPSR的第29位C,进位标志位(Carry)。一般情况下,进行无符号数的运算。
    加法运算:当运算结果产生了进位时(无符号数溢出),C=1,否则C=0
    减法运算(包括CMP):当运算时产生了借位时(无符号数溢出),C=0,否则C=1
  • CPSR的第28位是V,溢出标志位(Overflow)。在进行有符号数运算的时候,
    如果超过了机器所能标识的范围,称为溢出。

指令格式

ARM 指令流是一连串的字对齐的四字节指令流。每个 ARM 指令是一个单一的 32 位字(4字节),如图(3)

解读
图为ARM指令的编码一级格式,所有的指令

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值