Assembly 写一个程序来清除第7位和第6位,设置第5位和第4位,并切换第3位、第2位、第1位和第0位?
内存中地址为$9000的字节 编写一个程序以清除位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
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
..的一部分)