ARM循环程序和子程序设计

发布于:2024-12-18 ⋅ 阅读:(60) ⋅ 点赞:(0)

        1、计算下列两组数据的累加和并存入到sum1和 sum2 单元中。datal:0x12,0x935,0x17,0x100,0x95,0x345。

data2:0x357,0x778,0x129,0x188,0x190,0x155,0x167。

1.定义数据段

;定义数据段,类型为data(表示为数据段),权限为可读可写(程序可以读取和修改这里的数据)
    area datasegment,data,readwrite
data1 dcd 0x12, 0x935, 0x17, 0x100, 0x95, 0x345,0x0
data2 dcd 0x357, 0x778, 0x129, 0x188, 0x190, 0x155, 0x167,0x0
sum1 dcd 0
sum2 dcd 0
    end ;程序结束,对应entry

2.定义代码段

 ;定义代码段,数据类型为code(表示为代码段),权限为只读
    area codesegment,code,readonly
    entry ;程序入口
start
    ldr r0,=data1 ;将data1的地址加载到r0中
    ldr r1,=sum1 ;将sum1的地址加载到r1中
    bl sum
    nop
    ldr r0,=data2
    ldr r1,=sum2
    bl sum ;调用子程序
endpoint b .

sum
    mov r2,r0 ;r2对应data
    mov r3,r1 ;r3对应sum
loop
    ldr r4,[r2],#4 ;将r2地址对应的值放到r4,r2向后移动4字节
    cmp r4,#0
    beq exit  ;判断r4是否是data的结尾,是就进入exit
    add r5,r5,r4 ;r5=r5+r4
    b loop
exit
    str r5,[r3] ;将r5的值存储到r3地址对应的值上面
    mov r5,#0 ;将r5置为0
    mov pc,lr  ;回到调用子程序的地方

3.调试程序

                将data1的首地址存放到r0中,也就是0x8058,在Memory窗口中输入0x8050,然后找到第8个字节就可以看到存放了12,间隔4个字节存放0x935,而且是小端序存放,高位9在高地址d,地位35在低地址c。

在exit段设置断点,然后执行到此处,查看r5的值为0xE38,也就是data1数据的和。

        将r5的值存储到r1地址对应的空间上面,跳出循环,r1的地址为0x8094,在Memory视图查看0x8090的第4个字节可以找到38,第5个字节找到0E,刚好就是data1的和0xE38,存储方式为小端序。

        

再次调用子程序计算data2的和,得到0x11CC。

        由于sum1和sum2的地址,所以在Memory视图的0x8090的第8个字节和第9个字节处就是sum2的值,同样是小端序。

2、在字符串中搜索关键词,并返回关键词所在位置存储到order单元中。关键词:String

字符串:“string123456-St-abcd Stringabc.”

1.定义数据段

  ; 定义数据段
    area datasegment, data, readwrite
res     dcb "String", 0          ;S的十六进制码是53
dest    dcb "string123456-St-abcd Stringabc.", 0 ;s的十六进制码是73
order   dcb 0                     ; 存放关键词位置的单元

2.定义代码段

; 定义代码段
    area codesegment, code, readonly
    entry
start
    ldr r0, =res                 
    ldr r1, =dest                
    ldr r4, =order               
    mov r5, #0  ;计数器
    mov r6, #0  ;用于记录res的长度
    bl findstr
endpoint b .                 

findstr
    add r5, r5, #1                ; 增加位置计数器
    ldrb r2, [r1], #1             ; 将r1的字符放到r2,r1移动一个字节
    cmp r2, #0                    ; 检查是否到达字符串结尾
    beq exit                      ; 如果到达结尾,退出
    
    
    ldrb r3, [r0],#1              ; 将r0的字符放到r3,r0移动一个字节
    add r6,r6,#1                  ; 增加res的长度
    cmp r3, #0                    ; 检查关键词是否到达结尾
    beq found                     ; 如果关键词结束,表示找到了

    cmp r2, r3                    ; 比较两个字符
    beq findstr                   ; 如果相等,继续搜索下一个字符

    ; 如果不相等,重置关键词并继续搜索下一个字符
    ldr r0, =res                  ; 重置关键词的地址
    mov r6,#0                     ; 重置res的长度
    b findstr                     ; 继续搜索

found
    sub r6,r6,#1
    sub r5,r5,r6                  ; r5-r6就是字符串的开始位置
    str r5, [r4]                  ; 将找到的位置存储到 order 单元
exit
    bx lr                         ; 返回
    end

3.调试程序

    将res的地址存放到r0中,将dest的地址存放到r1中,通过Memory视图可以查看dest和res字符串对应的16进制码。

设置断点到found处,可以发现r5的值为0x1C也就是28(刚好就是dest中String的末尾),r6的值为0x7,将r6减一变成0x6(String的长度),用r5-r6就可以得到22,也就是dest中String的开始位置。

将结果存放到order,也就是r4中就可以了。


网站公告

今日签到

点亮在社区的每一天
去签到