装配式制作开关、外壳结构

Make switch, case structure in assembly

如何在汇编程序中制作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
}

编译时你看到了什么?你的编译器是怎么解决的?

我想到了三种简单的方法来实现这一点,但并非所有方法都可以使用。首先也是最重要的是,if-then-else 树将始终有效,并且根据您的案例值有时是唯一明智的方法。

除此之外的所有其他内容都是 "it depends" 例如,您删除了您的评论并且您希望 0,1,2,3 将分数加三,而所有其他值不是...AND。 ..diode_num 可以是这些数字中的任何一个或其他值,例如 75。甚至 4。那么您 could/implement 就是:

if(diode_num&3) goto skip;
score+=3;
skip:

当然是在 C 中(如果您愿意,可以不使用 goto)或在您的汇编语言的语法中,无论目标是什么。

如果您提供的代码使得 diode_num 只能是 0,1,2,3 那么这不是死代码,但它会针对所有情况优化到 score+=3 并且开关会打开离开。

假设情况并非如此,另一个 "it depends" 是一个跳转 table 这不仅取决于您的案例值,还取决于指令集并取决于可能出现的所有可能值例如,在您提供的代码之外,假设您实际上为每种情况做了一些事情,因为您提供的代码大部分是死代码,它变成了

if(diode_on == 1) diode_on = 0;

你应该提供一个更好的例子。但是如果编译器和优化器可以看到你没有提供的代码,假设发现 diode_num 的可能值范围是 0-7,你想对 0,1,2,3 中的每一个做一些特殊的事情在您未指定的指令集中可以跳转 table,然后

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

如果编译器无法确定输入值的范围,它可能会或可能不会选择尝试跳转 table。

你可以让它更优化,假设 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 个字节(四个 32 位字),您只需将 or 或案例乘以 16 到基地址并跳转到那里,不需要跳转 table 只需要数学。如果案例是 1、2、3、4,你可以减去 1,然后乘以 16(左移 4),然后添加到基数并跳转到那里。

既然你是优化编译器,那么你总是可以使用 if then else 树来实现它,或者如果你更了解输入范围的细节、案例数量、每个案例的代码量(这是你应该编码并围绕它构建骨架的第一件事)和指令集,然后你可以优化。