首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >装配中的开关、机箱结构

装配中的开关、机箱结构
EN

Stack Overflow用户
提问于 2017-06-07 08:03:12
回答 1查看 2.5K关注 0票数 0

如何在汇编程序中实现开关、机箱结构?什么是正确的方式还是更多的方法?

这是我用C语言编写的代码,我想用汇编语言编写。

代码语言:javascript
复制
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语言中破坏路由的代码,我试着用汇编程序编写。

代码语言:javascript
复制
    #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
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-06-07 08:45:19

你在编译这个时看到了什么?你的编译器是如何解决这个问题的?

在我的头上有三种简单的方法来实现这一点,但并不是所有的方法都可以使用。首先也是最重要的是,如果-然后-否则的树将永远工作,而取决于你的情况,值有时是唯一明智的方式来做它。

除此之外的所有内容都是“这取决于”,例如,如果您去掉了您的注释,并且希望将0、1、2、3添加到分数中,那么所有其他值not...AND...diode_num都可以是这些数字中的任何一个,也可以是像75这样的其他值。甚至4.那么您可以/将其实现为:

代码语言:javascript
复制
if(diode_num&3) goto skip;
score+=3;
skip:

当然,在C语言中(如果你愿意的话没有goto ),或者在汇编语言的语法中,不管这是什么目标。

如果您提供的代码是这样的,那么diode_num只能是0、1、2、3,那么这不是死代码,而是对所有情况下的score+=3进行优化,然后切换就消失了。

假设情况并非如此,另一个“它取决于”是一个跳转表,它不仅取决于您的案例值,还取决于指令集和所有可能出现的值,例如,在您提供的代码之外,假设您实际上为每种情况做了一些事情,因为您提供的代码大多是死代码。

代码语言:javascript
复制
if(diode_on == 1) diode_on = 0;

你应该提供一个更好的例子。但是,如果编译器和优化器可以看到您没有提供的代码,并且发现diode_num的可能值范围为0-7,并且您希望对0、1、2、3中的每一个执行一些特殊的操作,并且在这个没有指定的指令集中有一个跳转表是可能的,那么

代码语言:javascript
复制
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,并且您想为每种情况做一些不同的事情,但是它非常简单,在这种情况下,我使用固定大小的指令来进行进一步的优化。

代码语言:javascript
复制
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树来实现这一点,或者如果您了解更多关于输入范围、用例数、每个大小写的代码数量(这是您应该首先编写代码并围绕它构建骨架)和指令集的详细信息,那么您可能可以进行优化。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44406905

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档