如何在汇编程序中创建switch,case结构?什么是正确的方式或更多的核心?
这是我在C中的代码,我想在汇编程序中编写。
if (diode_on == 1)
{
switch(diode_num)
{
case 0:
//score += 3;
break;
case 1:
//score += 3;
break;
case 2:
//score += 3;
break;
case 3:
//score += 3;
break;
default:
break;
}
diode_on = 0;
}
我的项目MMSP430F5XX需要这个。该项目的条件是一个破解例程用汇编语言编写。这是在C中破解例程的代码,我尝试用汇编语言编写。
#pragma vector=PORT2_VECTOR
__interrupt void port2handler(void)
{
__delay_cycles(1000);
if (diode_on == 1)
{
switch(diode_num)
{
case 0:
if((P2IFG & BIT4)!=0)
{
if ((P2IN & BIT4)==0)
//score += 3;
calculationScore(3);
}
else
//score--;
calculationScore(-1);
break;
case 1:
if((P2IFG & BIT5)!=0)
{
if ((P2IN & BIT5)==0)
//score += 3;
calculationScore(3);
}
else
//score--;
calculationScore(-1);
break;
case 2:
if((P2IFG & BIT6)!=0)
{
if ((P2IN & BIT6)==0)
//score += 3;
calculationScore(3);
}
else
//score--;
calculationScore(-1);
break;
case 3:
if((P2IFG & BIT7)!=0)
{
if ((P2IN & BIT7)==0)
//score += 3;
calculationScore(3);
}
else
//score--;
calculationScore(-1);
break;
default:
break;
}
P4OUT &= ~(BIT3 | BIT4 | BIT5 | BIT6); //gasimo diode
diode_on = 0;
}
P2IFG &= ~(BIT4 | BIT5 | BIT6 | BIT7); // brisanje flega
}
答案 0 :(得分:1)
你编译时看到了什么?你的编译器是如何解决它的?
在我的脑海中,有三种简单的方法可以实现这一点,但并非所有方法都可以使用。首先,if-then-else树将始终有效,并且根据您的情况,值有时是唯一理智的方法。
除此之外的其他所有事情都是"它取决于"所以说例如你把你的评论拿出来,你想要0,1,2,3将三个加到分数而所有其他值都不是...... AND ... diode_num可以是这些数字中的任何一个或其他一些值75.甚至4.然后你可以/实现这个:if(diode_num&3) goto skip;
score+=3;
skip:
当然是在C中(如果你愿意,没有goto)或者汇编语言的语法无论目标是什么。
如果您提供的代码是binary_num只能是0,1,2,3那么这不是死代码,但它会优化到所有情况下得分+ = 3并且开关消失。
假设情况不是另一个"它取决于"是一个跳转表,它不仅取决于您的案例值,还取决于指令集,并取决于所有可能的值,例如在您提供的代码之外,并假设您实际上为每个案例做了一些事情,如您提供的代码主要是死代码
if(diode_on == 1) diode_on = 0;
你应该提供一个更好的例子。但是如果编译器和优化器可以看到你没有提供的代码,并且让我们说发现binary_num的可能值范围是0-7并且你想为0,1,2,3和跳转表中的每一个做一些特殊的事情可以在你没有指定的指令集中,然后
load some_register,table_base_add
shift_left temp_register,diode_num,2 ;assuming 32 bit addresses
add some_register,temp_register
load another_register,[some_register]
branch_to another_register
table_base_add: .word table_base
.align
;jump table
table_base:
.word case0
.word case1
.word case2
.word case3
.word switch_end
.word switch_end
.word switch_end
.word switch_end
;case 0 code
case0:
do something
b switch_end
;case 1 code
case1:
do something
b switch_end
;case 2 code
case2:
do something
b switch_end
;case 3 code
case3:
do something
b switch_end
switch_end:
code after switch
如果编译器无法确定输入值的范围,它可能会也可能不会选择尝试跳转表。
你可以让它更加优化,让我们说binary_num的范围严格为0,1,2,3并且你想为每种情况做一些不同的事情,但它非常简单,在这种情况下我使用固定大小进一步优化的说明。
load some_register,base_add
shift_left temp_register,diode_num,4
add some_register,temp_register
branch_to some_register
base_add: .word base
base:
;case 0 code
one instruction
b switch_end
nop
nop
;case 1 code
one instruction
one instruction
one instruction
b switch_end
;case 2 code
one instruction
one instruction
b switch_end
nop
;case 3 code
one instruction
nop
nop
b switch_end
switch_end:
在这种情况下,假设每个案例有16个字节(4个32位字),你可以添加或者或者将案例时间16加到基址并跳转到那里,没有跳转表只需数学。如果案例是1,2,3,4你可以减去一个然后乘以16(向左移4)然后加到基数并跳到那里。
由于您是优化编译器,因此您始终可以使用if then else树来实现此功能,或者如果您了解更多有关输入范围的详细信息,案例数,每个案例的代码量(这是你应该编写和构建它周围的骨架的第一件事)和指令集然后你可以优化。