首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Switch语句AVR-GCC

Switch语句AVR-GCC
EN

Stack Overflow用户
提问于 2013-02-01 02:45:11
回答 2查看 2.3K关注 0票数 0

嘿,这只是一个简单的程序,我用c写的,在avr下编译的--gcc。相应的汇编代码也会发布。

仍然不能理解switch语句的汇编代码在做什么,任何帮助都会很好。谢谢。

代码语言:javascript
复制
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;

}

汇编代码:

代码语言:javascript
复制
    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

谢谢你们。

EN

回答 2

Stack Overflow用户

发布于 2015-08-19 04:19:05

下面是对这些行含义的详细解释:

代码语言:javascript
复制
+0000014B:   8189        LDD       R24,Y+1        Load indirect with displacement

在这里,myinput的值从内存复制到寄存器r24。在内存中,它位于地址Y+1。Y中的值是位于myinput字符之前的字节的地址。

代码语言:javascript
复制
+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)处继续执行。否则继续执行下一条指令。

代码语言:javascript
复制
+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)。

代码语言:javascript
复制
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调用。

代码语言:javascript
复制
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__!!

代码语言:javascript
复制
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。

代码语言:javascript
复制
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

清理并返回..。

我希望这能对你有所帮助(即使很晚了),如果不能,希望它能帮助那些在搜索中找到这篇文章的人,同时也有类似的问题!

票数 2
EN

Stack Overflow用户

发布于 2013-02-01 02:54:01

偏移量0000014C比较"myInput“和”a“(ASCII97,十六进制0x61),如果相等,则跳转到偏移量00000151 (在BREQ点是PC+4,偏移量0000014D,因为流水线的获取部分在执行部分之前)。

如果比较失败,则将其与'b‘(偏移量0000014E)进行比较,并再次进行相应分支。

如果失败了,我们就跳到最后一个案例。

注意,我们如何调用printf (调用0x2A9)以及它返回的位置有一些微妙之处。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14632888

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档