Assembly code for a switch statement using AVR-GCC

江枫思渺然 提交于 2019-12-23 05:25:51

问题


Hey I am having trouble understanding the assembly code omitted by the compiler for the following switch statemet. It is different than the usual assembly code I see from using gcc etc.

switch(instr) { 
case OP_NOP: 
    break;

case OP_BIPUSH: 
    stack_push(arg0.z.bh); pc_inc = 2; break;
} 

Assembly code for the above C code:

switch(instr){ 
+00001482: 8529 LDD R18,Y+9 Load indirect with displacement 
+00001483: 2F82 MOV R24,R18 Copy register 
+00001484: E090 LDI R25,0x00 Load immediate 
+00001485: 01FC MOVW R30,R24 Copy register pair 
+00001486: 9732 SBIW R30,0x02 Subtract immediate from word 
+00001487: 3BED CPI R30,0xBD Compare with immediate 
+00001488: 05F1 CPC R31,R1 Compare with carry 
+00001489: F008 BRCS PC+0x02 Branch if carry set 
+0000148A: C39D RJMP PC+0x039E Relative jump 
+0000148B: 57E0 SUBI R30,0x70 Subtract immediate 
+0000148C: 4FFF SBCI R31,0xFF Subtract immediate with carry 
+0000148D: 0FEE LSL R30 Logical Shift Left 
+0000148E: 1FFF ROL R31 Rotate Left Through Carry 
+0000148F: 9005 LPM R0,Z+ Load program memory and postincrement 
+00001490: 91F4 LPM R31,Z Load program memory 
+00001491: 2DE0 MOV R30,R0 Copy register 
+00001492: 9409 IJMP Indirect jump to (Z) 
2003: stack_push(arg0.z.bh); pc_inc = 2; 
+00001493: 2D85 MOV R24,R5 Copy register 
+00001494: 2799 CLR R25 Clear Register 
+00001495: FD87 SBRC R24,7 Skip if bit in register cleared 
+00001496: 9590 LAT R25 Load and Toggle 
+00001497: C338 RJMP PC+0x0339 Relative jump 

I presume the code in case: NOP is getting optimized away by the compiler.

But I am having just understanding how the code is setting up the lookup table for the cases??

Any help would be great, thanks.


回答1:


There is only one case to check in your example, so it just checks if instr is equal to OP_BIPUSH. If it is then, skip ahead to do the rest, otherwise return from the function call.

At the start of the call, the Y register (which is really two general purpose registers, I forget which) points to the top of the stack. The parameter instr is 9 spots down the stack, and gets loaded into r24. r25 gets 0, so the pair contains the value of instr.

We only need to test against one thing, so subtract 2 and compare to 0xBD. (r1 is the zero register. It always contains 0.)

If the results are equal, then skip over the next instruction and continue through the rest of them. If they are not equal, then execute the next instruction, which returns from the function call with a jump.



来源:https://stackoverflow.com/questions/14616144/assembly-code-for-a-switch-statement-using-avr-gcc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!