若R1=0x40000000,R2=0x40000001,R3=0x40000002,R4=0x40000003,R5=0x40000004,R6=0x40000005;存储器0x40000000字单元的内容为 0x11, 0x40000004字单元的内容为0x22,0x40000008字单元的内容为 0x33,0x4000000C字单元的内容为0x44。问指令 LDMIA R1!,{R2-R4,R6}执行完之后,R1、R2、R3、R4、R5、R6的值为多少?
时间: 2023-06-04 10:08:58 浏览: 139
经过 LDMIA R1!,{R2-R4,R6} 指令执行后,R1 的值将会加上 16(因为加载了 5 个字单元),变成 0x40000010,同时 R2-R4, R6 中的值分别是存储器中地址为 0x40000000 字单元到 0x40000008字单元的值,即 0x11、0x40000001、0x40000002、0x33、0x40000005。而由于没有加载 R5 的值,R5 的值不会改变,仍然是 0x40000004。因此,LDMIA R1!,{R2-R4,R6} 执行后,R1 = 0x40000010,R2 = 0x00000011,R3 = 0x40000001,R4 = 0x40000002,R5 = 0x40000004,R6 = 0x00000033。
相关问题
Crash reason: SIGSEGV /SEGV_MAPERR Crash address: 0xaef15000 Process uptime: not available Thread 0 (crashed) 0 libQtGui.so.4 + 0x29531a r0 = 0x00bb80b6 r1 = 0x00bb00b6 r2 = 0x00000011 r3 = 0xff000000 r4 = 0xbac6b57a r5 = 0x00d300cd r6 = 0xaef15000 r7 = 0x02380124 r8 = 0x00ff0000 r9 = 0x02380124 r10 = 0x00000000 r12 = 0xaef15011 fp = 0x0000000f sp = 0xbee2c2c0 lr = 0xaef15000 pc = 0xb64ae31a Found by: given as instruction pointer in context 1 rtm2!google_breakpad::LinuxPtraceDumper::GetThreadInfoByIndex(unsigned int, google_breakpad::ThreadInfo*) [linux_ptrace_dumper.cc : 224 + 0xa] sp = 0xbee2c2d8 pc = 0x0001ec08 Found by: stack scanning 2 0xffee9b0b r4 = 0xffee9b0d r5 = 0xffee9b0d r6 = 0xffee9b0d r7 = 0xffee9b0d r8 = 0xffee9b0d r9 = 0xffee9b0d r10 = 0xffee9b0d fp = 0xffee9b0d sp = 0xbee2c418 pc = 0xffee9b0d Found by: call frame info 3 libQtGui.so.4 + 0x28e565 sp = 0xbee2c430 pc = 0xb64a7567 Found by: stack scanning 这段是什么意思?
这段是一段程序崩溃的日志信息,其中包含了崩溃的原因、地址、进程运行时间、线程信息等。
Crash reason: SIGSEGV /SEGV_MAPERR 表示崩溃的原因是段错误,这是指程序试图访问不属于其自己的内存区域。
Crash address: 0xaef15000 是崩溃发生时程序访问的非法内存地址。
Process uptime: not available 表示无法获取进程运行时间。
Thread 0 (crashed) 0 libQtGui.so.4 0x29531a 是崩溃发生时调用堆栈中的第一个函数调用,并且这个函数在 libQtGui.so.4 库中,在 0x29531a 位置发生崩溃。
r0-r12,fp,sp,lr,pc是程序在崩溃时的寄存器值。
Found by: given as instruction pointer in context 1 rtm2!google_breakpad::LinuxPtraceDumper::GetThreadInfoByIndex(unsigned int, google_breakpad::ThreadInfo*) [linux_ptrace_dumper.cc : 224 0xa] 表示这些信息是由LinuxPtraceDumper来收集的。
总之,这段日志信息表明程序在libQtGui.so.4库中的0x29531a位置发生了段错误,导致程序崩溃。
实验内容 使用 MOV 和 MVN 指令访问 ARM 通用寄存器;使用 ADD、SUB、AND、ORR、CMP、 TST 等指令完成数据加减运算及逻辑运算。 (1) 使用 MOV、ADD 指令实现:R8 = R3 = X + Y (2) 使用 MVN、SUB 指令实现:R5 = 0x5FFFFFF8 - R8 * 8 (3) 使用 CMP 指令判断(5*Y/2)>(2*X)吗?若大于则 R5 = R5&0xFFFF0000, 否则 R5 = R5|0x000000FF (4) 使用 TST 指令测试 R5 的 bit23 是否为 1,若是则将 bit6 位清零(使用 BIC 指令)
本实验的目的是熟悉 ARM 汇编语言中的 MOV、MVN、ADD、SUB、AND、ORR、CMP、TST、BIC 等指令的使用方法,以及掌握数据加减运算和逻辑运算的实现方法。通过本实验,我将学会如何使用这些指令完成一些基本的数据操作任务。
实验步骤如下:
1. 使用 MOV 和 ADD 指令实现:R8 = R3 = X + Y
```
MOV R3, #X
MOV R4, #Y
ADD R8, R3, R4
```
这里,X 和 Y 分别用常量表示,MOV 指令用来将常量加载到寄存器中,ADD 指令用来将 R3 和 R4 寄存器中的数据相加,并将结果存储到 R8 中。
2. 使用 MVN 和 SUB 指令实现:R5 = 0x5FFFFFF8 - R8 * 8
```
MOV R1, #0x5FFFFFF8
MVN R8, R8
ADD R8, R8, #1
LEA R0, [R8, LSL #3]
SUB R5, R1, R0
```
这里,首先使用 MOV 指令将常量 0x5FFFFFF8 加载到 R1 寄存器中,然后使用 MVN 指令对 R8 寄存器中的数据取反,使用 ADD 指令将 R8 寄存器中的数据加 1,使用 LEA 指令将 R8 寄存器中的数据左移 3 位(相当于乘以 8),并将结果存储到 R0 中,最后使用 SUB 指令将 R1 寄存器中的数据减去 R0 寄存器中的数据,并将结果存储到 R5 中。
3. 使用 CMP 指令判断 (5*Y/2)>(2*X) 吗?若大于则 R5 = R5&0xFFFF0000,否则 R5 = R5|0x000000FF
```
MOV R2, #Y
MOV R3, #X
MOV R4, #5
MOV R5, #2
MUL R2, R4, R2
SDIV R2, R2, R5
MUL R3, R3, R5
CMP R2, R3, LSL #1
BHI set_high
MOV R6, #0x000000FF
ORR R5, R5, R6
B end_if
set_high:
AND R6, R5, #0xFFFF0000
end_if:
```
这里,首先使用 MOV 指令将常量 X 和 Y 加载到 R3 和 R2 寄存器中,然后使用 MOV 指令将常量 5 和 2 加载到 R4 和 R5 寄存器中,使用 MUL 指令计算 5*Y,使用 SDIV 指令将结果除以 2,使用 MUL 指令计算 2*X,然后使用 CMP 指令将两个结果进行比较。如果 5*Y/2 大于 2*X,则跳转到 set_high 标签处将 R5 寄存器的高 16 位赋值为 0xFFFF,否则跳转到 end_if 标签处将 R5 寄存器的低 8 位赋值为 0xFF。
4. 使用 TST 指令测试 R5 的 bit23 是否为 1,若是则将 bit6 位清零(使用 BIC 指令)
```
TST R5, #0x00800000
BNE clear_bit6
B end_program
clear_bit6:
BIC R5, R5, #0x00000040
end_program:
```
这里,使用 TST 指令测试 R5 寄存器的 bit23 是否为 1,如果是,则跳转到 clear_bit6 标签处将 R5 寄存器的 bit6 清零,否则跳转到 end_program 标签处结束程序。
通过以上步骤,就可以完成本实验的目标。
实验总结:本实验通过编写汇编程序来实现了数据加减运算和逻辑运算,并学习了 MOV、MVN、ADD、SUB、AND、ORR、CMP、TST、BIC 等指令的使用方法。同时,还学习了如何使用汇编语言来进行常量的加载、寄存器的操作等基本操作,这对我今后的 ARM 开发工作非常有帮助。