如何在汇编程序中实现开关、机箱结构?什么是正确的方式还是更多的方法?
这是我用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
}发布于 2017-06-07 08:45:19
你在编译这个时看到了什么?你的编译器是如何解决这个问题的?
在我的头上有三种简单的方法来实现这一点,但并不是所有的方法都可以使用。首先也是最重要的是,如果-然后-否则的树将永远工作,而取决于你的情况,值有时是唯一明智的方式来做它。
除此之外的所有内容都是“这取决于”,例如,如果您去掉了您的注释,并且希望将0、1、2、3添加到分数中,那么所有其他值not...AND...diode_num都可以是这些数字中的任何一个,也可以是像75这样的其他值。甚至4.那么您可以/将其实现为:
if(diode_num&3) goto skip;
score+=3;
skip:当然,在C语言中(如果你愿意的话没有goto ),或者在汇编语言的语法中,不管这是什么目标。
如果您提供的代码是这样的,那么diode_num只能是0、1、2、3,那么这不是死代码,而是对所有情况下的score+=3进行优化,然后切换就消失了。
假设情况并非如此,另一个“它取决于”是一个跳转表,它不仅取决于您的案例值,还取决于指令集和所有可能出现的值,例如,在您提供的代码之外,假设您实际上为每种情况做了一些事情,因为您提供的代码大多是死代码。
if(diode_on == 1) diode_on = 0;你应该提供一个更好的例子。但是,如果编译器和优化器可以看到您没有提供的代码,并且发现diode_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如果编译器无法确定输入值的范围,它可能选择也可能不选择尝试跳转表。
您可以让它更加优化,假设diode_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,你可以减去1,然后乘以16 (移位左4),然后加到基座,然后跳到那里。
因为您是优化编译器,所以您总是可以使用if然后else树来实现这一点,或者如果您了解更多关于输入范围、用例数、每个大小写的代码数量(这是您应该首先编写代码并围绕它构建骨架)和指令集的详细信息,那么您可能可以进行优化。
https://stackoverflow.com/questions/44406905
复制相似问题