Assembly 写一个程序来清除第7位和第6位,设置第5位和第4位,并切换第3位、第2位、第1位和第0位?

Assembly 写一个程序来清除第7位和第6位,设置第5位和第4位,并切换第3位、第2位、第1位和第0位?,assembly,bit-manipulation,68000,easy68k,Assembly,Bit Manipulation,68000,Easy68k,内存中地址为$9000的字节 编写一个程序以清除位7和6,设置位5和4,并切换位3、2、1和0 这就是我所拥有的,它不起作用 ORG $9000 MOVE.B #00, D0 MOVE #7, D1 BCLR #7, D0 NEXT BTST D1,D0 BEQ ZERO BCHG #7,D0 ZERO SUB.B #1,D1

内存中地址为$9000的字节

编写一个程序以清除位7和6,设置位5和4,并切换位3、2、1和0

这就是我所拥有的,它不起作用

     ORG    $9000
    
        MOVE.B  #00, D0
   
        MOVE    #7, D1
        BCLR    #7, D0

NEXT    BTST    D1,D0

        BEQ     ZERO
        BCHG    #7,D0

ZERO    SUB.B   #1,D1

        BCC     NEXT
        
EXIT    TRAP    #14

        END     $9000

任何帮助都将不胜感激

我不知道68k汇编,但为什么会有这么长的程序,为什么需要比较和跳转,而这只是一些简单的按位操作。这是一个C语言的实现

a&=0x3f;//0011 1111清除位7和6
a |=0x30;//0011 0000设置位5和4
a^=0x0f;//0000 1111切换位3~0
当转换为组装时,它只需要3个简单的操作(不包括可变负载和3个恒定负载,如果需要的话),根本不需要跳转和比较

。Browncc编译为

bitwise:
        move.b 7(%sp),%d0
        and.b #63,%d0
        or.b #48,%d0
        eor.b #15,%d0
        rts

伪代码中显示的内容可以轻松完美地转换为68K,只需加载一个带值的寄存器,然后执行操作(移动到某处,d0和.b#$3f,d0或.b#$30,d0或.b#$0f,d0)。实际上
a=((a&x)y)^z)
总是可以用两个逻辑操作来表示(如果
x,y,z
是常量):
a&=(x&~y);a^=(z^y);
此外,
move.bmem,d0;和.b#x,d0;
可以稍微高效一些:
moveq#x,d0;和.bmem,d0;
(编译器编写者似乎不再优化他们的68k后端了……)@chtz我一直相信优化这个是可能的,但从来没有费心去做。这很聪明,但是像这样编写单独的表达式可能更可读。如果你在上面的链接中查看Clang的输出,你会惊讶于它生成的代码量添加
-fomit frame pointer
似乎有帮助(不知道为什么这不是
-O2
..的一部分)