您的位置:首页 > 其它

arm汇编实验-arm指令集的应用

2015-09-20 22:01 507 查看

实验一:

新建工程asm_test3.Uv2, 新建文件asm_test3.s 实现如下功能:先将R1中的低16位传送给R2的高16位,再将R2中的高8位数据传送到R3中的低8位中。

代码:

AREA test2,CODE,READONLY
    ENTRY
start
    MOV R1, #0xff
    MOV R2, R1, LSL #0x10;R1的低16位传送给R2的高16位 
    MOV R3, R2, LSR #0x14;R2的高8位传送给R3的低8位
    NOP
    END


心得:

1、立即数范围0-255,6789H表示十六进制常数

2、循环移位:循环左移时移出的位不仅要进CF,而且还要补空出的位

3、检测立即数是否有效的方法:

4、算术左移和逻辑左移在右边空出的位上填0

5、算术右移时,左边空出的位上填符号位(1表示负数,0表示正数),逻辑右移时,左边空出的位上填0。

实验二:

实现求和运算:1+2+3+4+5+…+100

代码:

AREA TEST3,CODE,READONLY
    ENTRY    
start
    MOV R0, #0
    MOV R1, #0
    MOV R2, #0
loop
    ADD R1, R1, #1                  ;next value in the register R1:R1_next = R1 + 1
    ADD R0, R0, R1                  ;R0 += R1
    SUBS R2, R1, #100       ;R1 is Variable for controling the cycle
    BNE loop
    END


心得:

1、关于算术运算如何影响CPSR的条件标志位需要知道CPSR里的条件标志位的含义,如下图:



2、如何根据算术运算的结果来使用条件码,需要知道条件码与CPSR的条件标志位的映射关系,如下图:




3、当有后缀S时,这些指令根据结果更新标志N和Z,在计算Operand2时更新标志C,不影响标志V。

实验三:

新建工程test4.uvproj, 在asm_test4.S文件中依次实现如下功能:

1、使用MOV、ADD指令实现:R8 = R3 = X + Y

2、使用MOV、SUB、LSL指令实现:R5 = 0x5FFFFFF8 - R8 * 8

3、使用CMP指令判断(5*Y/2)>(2*X)吗?若大于则R5 = R5 & 0xFFFF0000,否则R5 = R5|0x000000FF

4、使用TST指令测试R5的bit23是否为1,若是则将bit6位清零(使用BIC指令)

代码(version1):

X       EQU     11      ; 定义X的值为11
Y       EQU     8           ; 定义Y的值为8

BIT23       EQU     (1<<23)         ; 定义BIT23的值为0x00800000

    AREA    test4,  CODE, READONLY      ;声明代码段test4
    ENTRY                                                       ;标识程序入口
    CODE32                                                  ;申明32位arm指令
start
    ; 使用MOV、ADD指令实现:R8 = R3 = X + Y
    MOV R1, #X          ;R1 = X, if X = 1
    MOV R2, #Y          ;R2 = Y, if Y = 2
    ADD R3, R1, R2  ;R3 = X + Y, if R3 = 3
    MOV R8, R3          ;R8 = R3, if R8 = 3

    ; 使用MVN、SUB指令实现:R5 = 0x5FFFFFF8 - R8 * 8
    MVN R5, #0xA0000007
    SUB R5, R5, R8, LSL #3 ;if R5 = 0x5FFFFFF8 - R8 * 8

    ; 使用CMP指令判断(5*Y/2)>(2*X)吗?若大于则R5 = R5&0xFFFF0000,否则R5 = R5|0x000000FF
    MOV R2, R2, ASR #1       ;if Y / 2
    ADD R2, R2, R2, LSL #2       ;if R2 = Y + 4 * Y
    MOV R1, R1, LSL #1                  ;if R1 = 2*X

    CMPHI R2, R1                              ;unsigned >
    BNE CALLA
    ORR R5, R5, #0x000000FF     ;   R5 = R5|0x000000FF
CALLA   
    MOV R4, #0xFF000000
    ORR R4, R4, #0x00FF0000;R4 = 0xFFFF0000
    AND R5, R5, R4      ;   R5 = R5 & 0xFFFF0000

 ; 使用TST指令测试R5的bit23是否为1,若是则将bit6位清零(使用BIC指令)
    TST R5, #0x00800000     ;if bit23 = 1
    BNE CALLB
CALLB
    BIC R5, #0x00000040         ;bit6 = 0
    END


代码(version2):

X       EQU     11          ; 定义X的值为11
Y       EQU     8           ; 定义Y的值为8

BIT23   EQU     (1<<23)     ; 定义BIT23的值为0x00800000

            AREA    test2,CODE,READONLY ; 声明代码段test2
            ENTRY               ; 标识程序入口
            CODE32              ; 声明32位ARM指令

START       ; 使用MOV、ADD指令实现:R8 = R3 = X + Y
            MOV     R0,#X       ; R0 <= X,X的值必须是有效立即数
            MOV     R1,#Y       ; R1 <= Y,Y的值必须是有效立即数
            ADD     R3,R0,R1    ; 即是R3 = X + Y
            MOV     R8,R3       ; R8 <= R3

            ; 使用MVN、SUB指令实现:R5 = 0x5FFFFFF8 - R8 * 8
            MVN     R0,#0xA0000007      ; 0xA0000007的反码为0x5FFFFFF8
            SUB     R5,R0,R8,LSL #3     ; R8左移3位,结果即是 R8 * 8

            ; 使用CMP指令判断(5*Y/2)>(2*X)吗?若大于则R5 = R5&0xFFFF0000,否则R5 = R5|0x000000FF
            MOV     R0,#Y
            ADD     R0,R0,R0,LSL #2     ; 计算R0 = Y + 4*Y = 5*Y
            MOV     R0,R0,LSR #1        ; 计算R0 = 5*Y/2
            MOV     R1,#X
            MOV     R1,R1,LSL #1        ; 计算R1 = 2*X
            CMP     R0,R1               ; 比较R0和R1,即(5*Y/2)和(2*X)进行比较
            LDRHI   R2,=0xFFFF0000      ; 若(5*Y/2)>(2*X),则R2 <= 0xFFFF0000
            ANDHI   R5,R5,R2            ; 若(5*Y/2)>(2*X),则R5 = R5&R2
            ORRLS   R5,R5,#0x000000FF   ; 若(5*Y/2)≤(2*X),则R5 = R5|0x000000FF

            ; 使用TST指令测试R5的bit23是否为1,若是则将bit6位清零(使用BIC指令)
            TST     R5,#BIT23
            BICNE   R5,R5,#0x00000040           

            B       START

            END


心得:

1、除2的n次方幂运算都可以 转换位向右移n位的运算

2、乘运算都可以 转换为加运算和向左移n位的复合运算

3、跳转指令通常会和比较指令或算术逻辑运算指令组合使用,而跳转的策略由编程者自己灵活决定,基本原则是根据CPSR里的条件标志位来决策

4、跳转的范围-32MB到32MB

5、指令TST与AND的区别是不保存运算结果,只影响条件标识位,如果它测试的位全都是1时,标志位Z=1,这时条件码EQ将被判断为真,否则标志位Z=0,这时条件码NE将被判断为真

6、指令条件执行方式能减少汇编指令,可以提高程序的执行效率,因为在条件判断为真时,指令才执行,可以实现C语言里的if else结构,比如代码段

CMP     R0,R1               ; 比较R0和R1,即(5*Y/2)和(2*X)进行比较
            LDRHI   R2,=0xFFFF0000      ; 若(5*Y/2)>(2*X),则R2 <= 0xFFFF0000
            ANDHI   R5,R5,R2            ; 若(5*Y/2)>(2*X),则R5 = R5&R2
            ORRLS   R5,R5,#0x000000FF   ; 若(5*Y/2)≤(2*X),则R5 = R5|0x000000FF


它实现的一个if else结构,对应的伪代码是

if (5*Y/2)>(2*X)
then
    R5 = R5 & 0xFFFF0000
else
    R5 = R5|0x000000FF


7、关于常量,十进制,比如1、10;十六进制,比如0xff;n进制,形式n-XXX,比如8进制数8-587;字符常量,‘a’、’\t’;字符串常量,“cdf\t123”; 逻辑常量{TURE},{FALSE}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: