1、问:该程序完成了什么功能?答:该程序完成的功能:先把数据区堆栈中的17这七个数据送给R0R0寄存器,然后又把寄存器列表中的R0R7存入堆栈,然后又依次把堆栈中的17这七个数送给R3R6,R0R2,然后程序就结束了,在取数和存数的过程中。堆栈指针sp由0x0000变到0x8030再到0x804c,然后到0x8030,然后依次加4,最后到0x804c;程序计数器R15(PC)由0x8000地址依次加4 。二、LDMFD,STMFD伪代码实现的原理。指令STMFD和LDMFD分析:根据ATPCS规则,我们一般使用FD(Full Descending)类型的数据栈!所以经常使用的指令就有STMFD和L
2、DMFD,通过ARM对于栈操作和批量Load/Store指令寻址方式,可以知道指令STMFD和LDMFD的地址计算方法:STMFD指令的寻址方式为事后递减方式(DB)而DB寻址方式实际内存地址为:start_address = Rn - (Number_Of_Set_Bits_In(register_list)*4)end_address = Rn - 4STM指令操作的伪代码: if ConditionPassed(cond) then address = start_address for i = 0 to 15 if register_listi = 1 Memoryaddress =
3、Ri address = address + 4有上面两个伪代码可以得出 STMFD SP!,R0-R7,LR 的伪代码如下: SP SP 94; address =SP;for i = 0 to 7 Memoryaddress = Ri; address = address + 4;Memoryaddress = LR;LDMFD指令的寻址方式为事后递增方式(IA)IA内存的实际地址的伪代码start_address = Rnend_address = Rn + (Number_of_set_bits_in(register_list)*4) - 4LDM指令操作的伪代码(未考虑PC寄存器)
4、: Ri Memoryaddress,4所以LDMFD SP!,R0-R7,PC (;恢复现场,异常处理返回)伪代码是: address = SP; for i = 0 to 7 Ri = Memoryaddress ,4 address = address + 4; SP = address;作业2一、用移位操作完成(R0)*10运算。参考程序:mov R0,#10mov R1,R0,LSL #3mov R2,R0,LSL #1add R3,R1,R2stop: B stop二、已知数据缓冲池中有两组数据x和y,每组中有3个数据(例如x: 90,60,30,y: 60,40,20),将x中的
5、数据减去y中的数据,最后将两组数相减得到的结果送回到x中去!参考代码: LDR SP,=x,R0-R2,R3-R5 sub R2,R2,R5 Sub R1,R1,R4 Sub R0,R0,R3 x: .long 80,90,100 y: .long 10,20,30作业3已知R0和R1的值,要求保留R0的低16位,保留R1的高16位状态,最后将这两个值组成一个新的数送给R3.参考代码:LDR R0,=0x12345678LDR R1,=0x87654321ldr R2,=0xffffLDR R4,=0xffff0000AND R0,R0,R2AND R1,R1,R4ORR R3,R0,R1作业
6、4在ARM GNU环境下用ARM汇编语言编程序实现 LDR R0,=x LDR R1,=y LDR R2,R0 CMP R2,#0 BEQ ZERO BGT ZHENG BLT FUZERO: MOV R3,#0 STR R3,R1ZHENG: mov R3,R2FU: mvn R3,R2 mov R4,#0x1 add R3,R3,R4 B stop .long -10 .long 0作业5求20的阶乘:64位结果放在【R9:R8】中,R9放高32位,R放低32位思路:每轮乘法操作中,低32位(R8)乘以X(R0)后,结果的低32位放在R8中,高32位放在R9中;高32位R1乘以X(R0)后
7、再加上R9,得到64位结果的高32位,存入R9 MOV R8 , #20 低32位初始化为20 MOV R9 , #0 高位初始化为0 SUB R0,R8,#1 初始化计数器Loop: MOV R1 , R9 暂存高位值 UMULL R8 , R9 , R0 , R8 R9:R8=R0*R8 MLA R9 , R1 , R0 , R9 R9=R1*R0+R9 SUBS R0 , R0 , #1 计数器递减 BNE Loop 计数器不为0继续循环Stop: B stop二、已知a=R0,b=R1.while(ab) do if(ab) then a=a-belse a=b-a end ifend
8、 whileresult=a根据以上代码写出对应的汇编代码:CMP R0,R1CMPNE R0,R1SubGT R0,R0,R1SubLT R0,R1,R0作业61.将下面的ADS环境下的程序代码改写成GUN环境下的程序代码。(调试时使用F11 step into,注意和F10 step over的区别)AREA Jump, CODE, READONLY num EQU 4 ; 函数地址表内容的个数 ENTRY CODE32start LDR R0, =choice ; R0指向存储区的choice单元 LDR R0, R0 ; 设置第一个参数:选择执行哪一个函数 MOV R1, #16 ;
9、设置第1个操作数 MOV R2, #2 ; 设置第2个操作数 BL arithfunc ; 调用子程序arithfuncstop MOV R0, #0x18 ; 程序结束返回编译器调试环境 LDR R1, =0x20026 SWI 0x123456arithfunc CMP R0, #num ; 比较R0的值是否超过函数地址表的个数 MOVHS PC, LR ; 如果大于,那么就返回到标号stop处 ADR R3, JumpTable ; 将函数地址表的地址作为基地址 LDR PC, R3, R0, LSL #2 ; 根据R0参数进入对应的子程序JumpTable ; 函数地址表的入口基地址
10、DCD DoAdd ; 加法子程序 DCD DoSub ; 减法子程序 DCD DoMul ; 乘法子程序 DCD DoDiv ; 除法子程序DoAdd ADD R0, R1, R2 ; R0 = R1 + R2 MOV PC, LR ; 返回DoSub SUB R0, R1, R2 ; R0 = R1 - R2DoMul MOV R0, R1, LSL R2 ; R0 = R1 AREA NUM, DATA, READWRITEchoice DCD 3 ; 0:表示选择加法子程序 1:表示选择减法子程序 ; 2:表示选择乘法子程序 3:表示选择除法子程序 END.equ num,4 函数地址
11、表内容的个数 LDR R0,=choice R0指向存储区的choice单元 LDR R0,R0 设置第一个参数: MOV R1,#16 设置第1个操作数 MOV R2,#2 设置第2个操作数 Bl arithfunc 调用子程序arithfuncarithfunc: CMP R0,#num 比较R0的值是否超过函数地址表的个数 MOVHS PC, LR 如果大于,那么就返回到标号stop处 ADR R3, JumpTable 将函数地址表的地址作为基地址 LDR PC, R3, R0, LSL#2 根据R0参数进入对应的子程序JumpTable: 函数地址表的入口基地址 .long DoAdd 加法子程序 .long DoSub 减法子程序 .long DoMul 乘法子程序 .long DoDiv 除法子程序
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1