嵌入式编程
- 格式:doc
- 大小:45.00 KB
- 文档页数:5
4.4 利用跳转表实现具有下述功能的汇编程序:(1)当r0为1时,调用子程序CASE1,完成r1加r2把结果放入r3的计算;(2)当r0为2时,调用子程序CASE2,完成r1减r2把结果放入r3的计算;(3)当r0为3时,调用子程序CASE3,完成r1与r2把结果放入r3的计算;(4)否则,完成r1或r2把结果放入r3的计算。
参考程序AREA JumpTest,CODE,READONL Y ; 定义代码段CODE32 ; 设置为arm指令集ENTRY ; 程序入口startMOV r0, #1MOV r1, #3MOV r2, #2ADR r4, JumpTable ; 将跳转表地址送给r4CMP r0, #1 ; if r0==1 then CALL CASE1MOVEQ r3, #0LDREQ pc, [r4,r3,LSL #2]CMP r0, #2 ; if r0==2 then CALL CASE2MOVEQ r3, #1LDREQ pc, [r4,r3,LSL #2]CMP r0, #3 ; if r0==3 then CALL CASE3MOVEQ r3, #2LDREQ pc, [r4,r3,LSL #2]DEFAULT ; otherwise CALL DEFSULTORR r0, r1, r2SWITCHENDMOV r0, #0x18 ; 调用软中断返回操作系统LDR r1, =0x20026SWI 0x123456JumpTable ; 定义跳转表DCD CASE1DCD CASE2DCD CASE3CASE1 ; 子程序1ADD r3, r1, r2B SWITCHENDCASE2 ; 子程序2SUB r3, r1, r2B SWITCHENDCASE3 ; 子程序3AND r3, r1, r2B SWITCHENDEND4.5 冒泡法是一种经常用到的排序方法,试编程实现具有上述功能的程序。
提示:可以使用r4作为计数器,r1存放比较的起始地址,r6存放中止地址。
参考程序:AREA Sort, CODE, READONL YENTRYStart: MOV r4, #0;LDR r6, =Src;ADD r6, r6, #Len-4;Outer: LDR r1, =Src;Inner: LDR r2, [r1];LDR r3,[r1,#4];CMP r2, r3;STRGT r3, [r1];STRGT r2, [r1, #4];ADD r1, r1, #4;CMP r1, r6;BLT Inner;ADD r4, r4, #4;CMP r4, #len-4;SUBLT r6, r6, #4;BLT Outer;Stop: MOV r0, #0x18;LDR r1, =0x20026;SWI 0x123456;AREA Array, DATA, READWRITESrc DCD 2,4,10,8, 14,1,12Len EQU 76*4END4.7已知求取最大公约数的伪代码如下:int gcd ( int a, int b){while( a!=b) do{if (a>b) a=a-b;else b=b-a;}return a;}试将上面的程序用ARM汇编语言实现。
参考程序gcd CMP r0, r1;SUBGT r0, r0, r1;SUBLT r1, r1, r0;BNE gcdMOV pc, lr4.9 将由src开始的20个单元中的内容转移到由dst开始的单元中。
要求当欲传送的数据大于8时,采用多字节传送指令,每次传递8个字节,对于不足8个字节的数字采用单字节传送指令传递。
参考程序AREA Block, CODE, READONL Y ; name this block of codenum EQU 20 ; Set number of words to be copiedENTRY ; mark the first instruction to callstartLDR r0, =src ; r0 = pointer to source blockLDR r1, =dst ; r1 = pointer to destination blockMOV r2, #num ; r2 = number of words to copyMOV sp, #0x400 ; set up stack pointer (r13)blockcopyMOVS r3,r2, LSR #3 ; number of eight word multiplesBEQ copywords ; less than eight words to move ?STMFD sp!, {r4-r11} ; save some working registersoctcopyLDMIA r0!, {r4-r11} ; load 8 words from the sourceSTMIA r1!, {r4-r11} ; and put them at the destinationSUBS r3, r3, #1 ; decrement the counterBNE octcopy ; ... copy moreLDMFD sp!, {r4-r11} ; don't need these now - restore originalscopywordsANDS r2, r2, #7 ; number of odd words to copyBEQ stop ; No words left to copy ?wordcopyLDR r3, [r0], #4 ; a word from the sourceSTR r3, [r1], #4 ; store a word to the destinationSUBS r2, r2, #1 ; decrement the counterBNE wordcopy ; ... copy morestopMOV r0, #0x18 ; angel_SWIreason_ReportExceptionLDR r1, =0x20026 ; ADP_Stopped_ApplicationExitSWI 0x123456 ; ARM semihosting SWIAREA BlockData, DA TA, READWRITEsrc DCD 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4dst DCD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0END4.10 使用ADS1.2调试下面的源程序int main(void){char i;int sum=0;int data[4];data[0]=1;data[1]=2;data[2]=3;data[3]=4;for(i=0;i<4;i++){sum=sum+data[i];}return sum;}经过汇编后,对应的汇编程序如下:main * stmfd r13!,{r0-r3,r14} ;按照满递减方式将r14、r3-r0入栈000080ac mov r0,#0;sum=0;000080b0 mov r1,#1 ;数组初始化000080b4 str r1,[r13,#0]; r13数组起始地址000080b8 mov r1,#2000080bc str r1,[r13,#4]000080c0 mov r1,#3000080c4 str r1,[r13,#8]000080c8 mov r1,#4000080cc str r1,[r13,#0xc]000080d0 mov r1,#0;i=0000080d4 cmp r1,#4; compare i,4000080d8 bcs 0x80f0 ; (main + 0x48); if i>4 goto 80f0000080dc ldr r2,[r13,r1,lsl #2]: r2=data[i]000080e0 add r0,r2,r0; sum=sum+data[i]000080e4 add r1,r1,#1; i++000080e8 and r1,r1,#0xff; 将i转化为char类型000080ec b 0x80d4 ; (main + 0x2c)000080f0 add r13,r13,#0x10000080f4 ldr pc,[r13],#4;return阅读该程序并回答以下问题i、在ADS1.2中所使用的堆栈是什么类型的?ii、在ADS1.2中如何保证数据类型为无符号8位整型的?iii、上述程序中将数组保存在哪里?iv、入栈指令stmfd r13!, {r0-r3,r14}的入栈顺序是什么?4.11 使用ADS1.2调试下面的程序short checksum_v2(short *data){unsigned int i;short sum=0;for(i=0;i<64;i++){sum=(short)(sum+data[i]);}return sum;}经过反汇编后,获得如下的汇编程序:0x00000000 MOV r2,r0 ; r2=data0x00000004 MOV r0,#0 ; sum=0(短整型16bit)0x00000008 MOV r1,#0 ; i=00x0000000c ADD r3,r2,r1,LSL #1; r3=&0x00000010 LDRH r3,[r3,#0] ; r3=data[i]0x00000014 ADD r0,r3,r0 ; sum=sum+data[i]0x00000018 MOV r0,r0,LSL #16 ; 转换r0为短整型0x0000001c MOV r0,r0,ASR #160x00000020 ADD r1,r1,#1 ; i++0x00000024 CMP r1,#0x40 ; compare i, 640x00000028 BCC 0xc ; if (i<64) goto 0xc0x0000002c. MOV pc,r14 ; return sum阅读程序并回答如下问题。
(1)请为获得的反汇编语言加上注释。
(2)在ADS中如何实现短整型数据类型的?(3)在ADS中是如何读取短整型数据的?(4)在ADS中LDRH不支持位移地址偏移,那它是如何实现地址指针移动的?(5)若子程序中的中间变量无特殊要求,是选择为短整型还是选择为整型好,为什么?。