嘿,这只是一个简单的程序,我用c写的,在avr下编译的--gcc。相应的汇编代码也会发布。
仍然不能理解switch语句的汇编代码在做什么,任何帮助都会很好。谢谢。
int main()
{
char myinput;
printf("Which option will you choose:\n");
printf("a) Program 1 \n");
printf("b) Program 2 \n");
scanf("%c", &myinput);
switch (myinput)
{
case 'a':
printf("Run program 1\n");
break;
case 'b':
{
printf("Run program 2\n");
printf("Please Wait\n");
break;
}
default:
printf("Invalid choice\n");
break;
}
return 0;返回0;
}
汇编代码:
switch (myinput)
+00000147: 900F POP R0 Pop register from stack
+00000148: 900F POP R0 Pop register from stack
+00000149: 900F POP R0 Pop register from stack
+0000014A: 900F POP R0 Pop register from stack
+0000014B: 8189 LDD R24,Y+1 Load indirect with displacement
+0000014C: 3681 CPI R24,0x61 Compare with immediate
+0000014D: F019 BREQ PC+0x04 Branch if equal
+0000014E: 3682 CPI R24,0x62 Compare with immediate
+0000014F: F459 BRNE PC+0x0C Branch if not equal
+00000150: C003 RJMP PC+0x0004 Relative jump
22: printf("Run program 1\n");
+00000151: E38D LDI R24,0x3D Load immediate
+00000152: E092 LDI R25,0x02 Load immediate
+00000153: C009 RJMP PC+0x000A Relative jump
26: printf("Run program 2\n");
+00000154: E48B LDI R24,0x4B Load immediate
+00000155: E092 LDI R25,0x02 Load immediate
+00000156: 940E02A9 CALL 0x000002A9 Call subroutine
27: printf("Please Wait\n");
+00000158: E589 LDI R24,0x59 Load immediate
+00000159: E092 LDI R25,0x02 Load immediate
+0000015A: C002 RJMP PC+0x0003 Relative jump
31: printf("Invalid choice\n");
+0000015B: E685 LDI R24,0x65 Load immediate
+0000015C: E092 LDI R25,0x02 Load immediate
+0000015D: 940E02A9 CALL 0x000002A9 Call subroutine
38: }
+0000015F: E080 LDI R24,0x00 Load immediate
+00000160: E090 LDI R25,0x00 Load immediate
+00000161: 900F POP R0 Pop register from stack
+00000162: 91CF POP R28 Pop register from stack
+00000163: 91DF POP R29 Pop register from stack
+00000164: 9508 RET Subroutine return谢谢你们。
发布于 2015-08-19 04:19:05
下面是对这些行含义的详细解释:
+0000014B: 8189 LDD R24,Y+1 Load indirect with displacement在这里,myinput的值从内存复制到寄存器r24。在内存中,它位于地址Y+1。Y中的值是位于myinput字符之前的字节的地址。
+0000014C: 3681 CPI R24,0x61 Compare with immediate
+0000014D: F019 BREQ PC+0x04 Branch if equal这里将myinput的值(在r24中)与0x61='a‘(在ascii中)进行比较。如果它们相等(myinput=='a'),则在+00000151: (0x14D+0x4=0x0x151)处继续执行。否则继续执行下一条指令。
+0000014E: 3682 CPI R24,0x62 Compare with immediate
+0000014F: F459 BRNE PC+0x0C Branch if not equal
+00000150: C003 RJMP PC+0x0004 Relative jump这里再次将myinput值(以r24为单位)与0x62='b‘(以ASCII为单位)进行比较,但现在只有当它们不等于(默认情况)时,才会在+0000015B: (0x14F+0xC=0x0x15B)处继续执行。Else (myinput=='b')下一条指令是跳转到+00000154: (0x150+0x4=0x0x154)。
22: printf("Run program 1\n");
+00000151: E38D LDI R24,0x3D Load immediate
+00000152: E092 LDI R25,0x02 Load immediate
+00000153: C009 RJMP PC+0x000A Relative jump在'a'-casethe中,printf命令的参数(实际上是字符串的内存地址)存储在r25:r24中。然后,执行转移到+0000015D:处switch语句结束之前的最后一个printf调用。
26: printf("Run program 2\n");
+00000154: E48B LDI R24,0x4B Load immediate
+00000155: E092 LDI R25,0x02 Load immediate
+00000156: 940E02A9 CALL 0x000002A9 Call subroutine
27: printf("Please Wait\n");
+00000158: E589 LDI R24,0x59 Load immediate
+00000159: E092 LDI R25,0x02 Load immediate
+0000015A: C002 RJMP PC+0x0003 Relative jump在‘b’的情况下,与前面类似,要打印的字符串的地址存储在r25:r24中。然后,执行在存储器地址0x000002A9处调用printf子例程。则第二串的地址被加载到r25:r24,并且执行跳转到在+0000015E:处的switch语句结束之前对printf的最后一次调用。
在这里可以很好地看到,字符串存储在内存中,因为第一个字符串有14 (0xE)个字节(字符)长,位于0x3D02__;下一个字符串位于0x3D02+0xE=0x4D02__!!
31: printf("Invalid choice\n");
+0000015B: E685 LDI R24,0x65 Load immediate
+0000015C: E092 LDI R25,0x02 Load immediate
+0000015D: 940E02A9 CALL 0x000002A9 Call subroutine在默认情况下,和以前一样,字符串被加载到r25:r24,并调用printf。
38: }
+0000015F: E080 LDI R24,0x00 Load immediate
+00000160: E090 LDI R25,0x00 Load immediate
+00000161: 900F POP R0 Pop register from stack
+00000162: 91CF POP R28 Pop register from stack
+00000163: 91DF POP R29 Pop register from stack
+00000164: 9508 RET Subroutine return清理并返回..。
我希望这能对你有所帮助(即使很晚了),如果不能,希望它能帮助那些在搜索中找到这篇文章的人,同时也有类似的问题!
发布于 2013-02-01 02:54:01
偏移量0000014C比较"myInput“和”a“(ASCII97,十六进制0x61),如果相等,则跳转到偏移量00000151 (在BREQ点是PC+4,偏移量0000014D,因为流水线的获取部分在执行部分之前)。
如果比较失败,则将其与'b‘(偏移量0000014E)进行比较,并再次进行相应分支。
如果失败了,我们就跳到最后一个案例。
注意,我们如何调用printf (调用0x2A9)以及它返回的位置有一些微妙之处。
https://stackoverflow.com/questions/14632888
复制相似问题