嘿,我无法理解编译器为以下开关statemet省略的汇编代码。它与我使用gcc等看到的常用汇编代码不同。
switch(instr) {
case OP_NOP:
break;
case OP_BIPUSH:
stack_push(arg0.z.bh); pc_inc = 2; break;
}
上述C代码的汇编代码:
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
我假设代码是这样的:NOP正在被编译器优化掉。
但我刚刚理解代码是如何为案例设置查找表的?
任何帮助都会很棒,谢谢。
在您的示例中只检查一个案例,因此它只检查instr
是否等于OP_BIPUSH
。如果是,则向前跳过以执行其余操作,否则从函数调用返回。
在调用开始时,Y寄存器(实际上是两个通用寄存器,我忘了哪个)指向堆栈的顶部。参数instr
在堆栈下方有9个点,并被加载到r24中。 r25得0,所以该对包含instr
的值。
我们只需要测试一件事,所以减去2并与0xBD
比较。 (r1是零寄存器。它总是包含0.)
如果结果相同,则跳过下一条指令并继续完成其余指令。如果它们不相等,则执行下一条指令,该指令通过跳转从函数调用返回。