一步一步写ARM汇编(一)

基本指令学习

在博文:keil下ARM汇编程序建立与调试简介中学习建立ARM汇编程序工程。本博文开始学习一步一步写ARM汇编程序。

一、重要概念理解

1. 立即数

1)把数据转换成二进制形式,从低到高写成 4位1组的形式,最高位一组不够4位的前面补0

2)数1的个数,如果大于8个【可能也是立即数,取反】不是立即数,如果小于等于8个 进行下面步骤

3)如果数据中间有连续的大于等于24个0,循环左移2的倍数,使高位全为0

4)找到最高位的1,去掉前面的最大偶数个0

5)找到最低位的1,去掉后面偶数个0

6)数剩下的位数,如果小于等于8位,那么这个数就是个立即数,反之就不是立即数

举例:判断0x80000001是不是立即数

1)二进制形式:1000 0000 00000000 0000 0000 0000 0001

2)1的个数小于8个,进入第三步

3)循环左移2位,这步结果为:00 0000 0000 0000 0000 0000 0000 000110

4)这步结果为:0110

5)这步结果为:0110

6)满足条件,所以0x80000001是立即数

 

判断一个数是否是立即数的目的是:在汇编操作中,有些指令操作的数只能是立即数,比如

movr0,#0xnum ; num就必须是立即数。

 

2. 条件码,条件码:本条指令的执行,依赖于上一个指令的执行结果

一步一步写ARM汇编(一)_第1张图片

举例理解,比如寄存器中r0和r1分别保存两个数,如果r0小于r1,将r1值传给r0:  

cmp r0,r1 ;比较r0和r1,会有某个标志位记下它们比较的结果

movlt r0,r1 ;movlt = mov + lt ,查上表知为lt为带符号数小于,也就是说mov在r0< r1时,才执行mov操作。如何查看条件是否成立呢?cmpr0,r1执行后,cpu就查看cpsr中N是否等于V, 不等于是说明r0< r1成立,执行mov操作。

 

 

3. cpsr中各个标志位具体含义

 

标志位

含                                义

N

当用两个补码表示的带符号数进行运算时,N=1表示运算的结果为负数;N=0表示运算的结果为正数或零

Z

Z=1表示运算的结果为零,Z=0表示运算的结果非零。

C

可以有4种方法设置C的值:

 -加法运算(包括CMP):当运算结果产生了进位时(无符号数溢出),C=1,否则C=0。

 -减法运算(包括CMP):当运算时产生了借位时(无符号数溢出),C=0,否则C=1。

 -对于包含移位操作的非加/减运算指令,C为移出值的最后一位。

 -对于其它的非加/减运算指令,C的值通常不会改变。

V

可以有2种方法设置V的值:

 -对于加减法运算指令,当操作数和运算结果为二进制的补码表示的带符号数时,V=1表示符号位溢出

 -对于其它的非加/减运算指令,V的值通常不会改变。

Q

在ARM V5及以上版本的E系列处理器中,用Q标志位指示增强的DSP运算指令是否发生了溢出。在其它版本的处理器中,Q标志位无定义

 

 

二、基本指令练习

 

1. 两个寄存器值相加减,示例代码如下:

       areaexample,code,readonly

       entry

 

start

 

       ;r0+ r1 -> r2(注:前面带有; 表示注解)

       mov r0,#0x2

       movr1,#0x1

 

       addr2, r0, r1

 

       ;r0- r1 -> r2

     mov r0,#0x2

       movr1,#0x1

 

       subr2, r0, r1

 

       end

 

2. 两个寄存器值相与或异或,示例代码如下

       areaexample,code,readonly

       entry

 

start

 

       ;r0and r1

       movr0,#0x1

       movr1,#0x3

       andr0,r0,r1

 

       ;r0orr r1

       movr0,#0x2

       movr1,#0x1

       orrr0,r0,r1

 

       end

 

3.将特定的第几位清0,示例代码如下:

       areaexample,code,readonly

       entry

 

start

       ;bic将特定的位清0

     mov r0,#0xff

       movr1,#0x04 ;(0000 0100,将第3位清0)

       bicr2,r0,r1

 

       end

 

3. 逻辑左移或逻辑右移,示例代码如下

       areaexample,code,readonly

       entry

 

start

 

       ;逻辑左移低位补0,高位丢弃

       movr0,#0x1

       movr1,r0,lsl #1; r1 = r0 << 0

 

       ;逻辑右移低位丢弃,高位补0

       movr0,#0xf0000007

       movr1,r0,lsr #1

 

       end

4. 算数左移或算数右移,示例代码如下

       areaexample,code,readonly

       entry

 

start

 

       ;注:算数左移与逻辑左移是同一个指令都是lsl

 

 

       ;算数右移低位丢弃,高位补符号位

       movr0,#0xf0000007

       movr1,r0,asr #1

 

       end

 

5. 循环右移,示例代码如下

       areaexample,code,readonly

       entry

 

start

 

       ;循环右移 ror

       ;左端填充右端移出去的位

       ;11110000 0000 0000 0000 0000 0000 0111循环右移结果:1111 1000 00000000 0000 0000 0000 0011

       movr0, #0xf0000007

       movr1,r0,ror #1

 

       end

 

6. 带扩展位的循环右移,一次只能移一位,示例代码如下:

 

       areaexample,code,readonly

       entry

 

start

 

       ;带扩展位的循环右移唯一的一个不需要指定移位位数的指令

       ;移除去的位,移到 cpsr的 c位中

       movr0, #0xf0000007

       movsr1,r0,rrx ;注意带有s

 

       end

调试窗口如下:

一步一步写ARM汇编(一)_第2张图片

注1:r0 为 1111 0000 0000 0000 0000 0000 0000 0111

注2:r1 为 0111 1000 0000 0000 0000 0000 0000 0011,最右面的1移到CPSR寄存器中的C中

注3:r15(pc)保存cpu要执行的下一条指令的地址,这个地址保存的内容可以在Disassembly窗口中看到。

 

三、提高练习

1. 64 位加减,示例代码如下:

       areaexample,code,readonly

       entry

 

start

 

       ;64位加法,一个64位保存在r0和r1中,一个64位保存在r2和r3中

       movr0,#0xffffffff

       movr1,#0x1

 

       movr2,#0x1

       movr3,#0x1

 

       addsr0,r0,r2

       adc  r4,r1,r3

 

       ;64位减法,一个64位保存在r0和r1中,一个64位保存在r2和r3中

       movr0,#0x0

       movr1,#0x2

 

       movr2,#0x1

       movr3,#0x1

 

       subsr0,r0,r2 ;注意c借位为0,否则为1

       sbc  r4,r1,r3

 

       end

 

2. 求两个数差的绝对值,示例代码如下:

       areaexample,code,readonly

       entry

 

start

 

      ;取两个数差的绝对值

       movr0,#5

       movr1,#4

 

       cmpr0,r1

       beqover

       subgtr3,r0,r1

       subltr3,r1,r0

 

over

       bover

 

       end

 

3. 求3个数的最大数

       areaexample,code,readonly

       entry

 

start

 

       ;求3个数的最大数,将最大值保存在r0中

       mov r0,#3

       mov r1,#4

       mov r2,#5

 

       cmp r0,r1

       movlt r0,r1     ;如果r0 < r1, 将 r1 -> r0

 

       cmpr0,r2

       movltr0,r2     ;如果r0< r2, 将 r2 -> r0

 

       end

 

 

 

 


你可能感兴趣的:(ARM)