*我正在使用程序集8086(x86-32)
交易非常简单,我在寄存器AL(8位)中有一个字节大小的数字, 现在,我需要在寄存器AL中的第1位(右边的第二个)和第4位(右边的第五个)之间进行交换。
例如:如果Al有这个数字:00010000B现在它将有00000010B。
谢谢!
答案 0 :(得分:5)
一到两条指令回答:
and eax, $255; // mask off extra bits -- perhaps not needed, if upper bits are
mov al, look_up_table[eax] // guaranteed to be zero
仅使用al的三条说明。
test al, $0x12
jpe skip ;; parity was even (aka the bits are the same)
xor al, $0x12 ;; toggle both bits
skip:
操作原理:只有当它们不同时才需要交换位。 0更改为1和1更改为0通过xored xoring 1。 两个位同时受到影响。
如果存在条件cmovpo或cmovpe,则可以避免跳转。但在这种情况下,序列至少需要4条指令(取决于是否已知某些寄存器包含零或位掩码)。或者可以选择测试一个&掩码只有一位设置。这是通过表达式(a ==(a& -a))
完成的答案 1 :(得分:3)
你可以试试这个:
mov BL, AL
mov BH, AL
and BL, 2h //empty all bits except first
and BH, 10h //empty all bits except fourth
shl BL, 3 //move bit 1 to position of bit 4
shr BH, 3 //move bit 4 to position of bit 1
and AL, edh //empty first and fourth bits
or AL, BL //set bit 4
or AL, BH //set bit 1
AL寄存器包含结果。您也可能需要存储在寄存器BX中的数据。如果你这样做,那么用
预先添加解决方案push BX
end追加到最后
pop BX
答案 2 :(得分:1)
另一种选择(7条指令):
mov ebx,00010010b ;ebx = 00010010
and ebx,eax ;ebx = 000A00B0
lea ebx,[ebx+ebx*4] ;ebx = 0A0AB0B0
rol bl,5 ;ebx = AB0B00A0
and ebx,00010010b ;ebx = 000B00A0
and al,11101101b ;al = abc0ef0g
or al,bl ;al = abcBefAg
另一种选择(也是7条指令):
ror al,1 ;ax = ????????.gabcAefB
ror ax,1 ;ax = B???????.?gabcAef
ror al,3 ;ax = B???????.Aef?gabc
rol ax,1 ;ax = ???????A.ef?gabcB
rol al,3 ;ax = ???????A.gabcBef?
ror al,1 ;ax = ????????.AgabcBef
rol al,2 ;ax = ????????.abcBefAg
答案 3 :(得分:1)
我添加了我的六种指令替代方案:
xor bl, bl ; -> clear work register
btr ax, 1 ; -> second bit to carry, clear that bit in al
cmovc bl, 8 ; -> set bit at bitpos 3
btr ax, 4 ; -> fifth bit to carry, clear that bit in al
rcl bl, 2 ; -> set bit at bitpos 2, shift bitpos 3 -> 5
or al, bl ; -> merge bits
注意:这只是一项学术活动。您可能不希望使用btr指令的代码,因为它们很慢。至少我上次尝试使用它们。另外:未经测试。
需要486指令集。
答案 4 :(得分:1)
仅使用al的6条说明
; al | cf
; 76543210 | x
ror al, 5 ; 43210765 | x
bt al, 4 ; 43210765 | 1
rcl al, 4 ; 07651432 | 1
bt al, 2 ; 07651432 | 4
rcr al, 3 ; 32407651 | 4
rol al, 4 ; 76513240 | x