8086 如何反转寄存器中的一个字节
8086 how to reverse a byte in a register
如何在字节级别反转寄存器值?
mov al,12 -----> how can i reverse al value
to 21
这是我尝试过的方法:
mov bx,4321 ;i want to make bx 1234
mov cl,04 ;cl for rotation value
xchg bh,bl ; now bx will 2143
mov al,bh ;moving 21 to al
rol al,cl ; rotate al 4 times to left now al is 12`
mov bh,al ; bh is 12 setuped ,time for bl
;---------------------------
mov al,bl ;moving lower byte 43 to al
rol al,cl ; rotate 4 times to left now al will 34
mov bl,al ; moving 34 to bl
现在bx
必须包含一个颠倒的数字1234;问题是数字是十六进制,即 10e1h 或 4321。
我倒过来是1e01h,但是这个值不是1234
1234 是 04d2。我得到的值是 7681d.
要反转字节中的位,请使用查找 table。要反转字中的位,请使用查找 table 反转最低 8 位,然后使用 rol ax,8
,然后使用查找 table 反转其他 8 位。
要反转一个字节中的(4 位)半字节,请使用 rol al,4
。要反转单词中的半字节,请使用 rol al,4; rol ax,8; rol al,4
.
用于反转字节或字中的十进制数字;不。相反,更改打印十进制数字的代码。原因是从整数(例如值 1234)到字符串(例如字符“1234”)的转换通常会以相反的顺序生成字符,并且必须做额外的工作来反转字符;所以 "print_reversed_decimal()" 会做更少的工作(并且以其他方式反转数字然后在打印时再次反转它是白费两倍的工作量!)。或者,您可以改用 BCD(每个半字节包含一个十进制数字)。在这种情况下,您可以使用 "reverse nibbles" 方法反转十进制数字,然后打印数字变得更便宜(移位和掩码而不是除法和模数)。
请注意,反转整数中十进制数字的数学运算类似于:
k = 10000000;
result = 0;
while(value > 0) {
digit = input % 10;
result += digit * k;
input /= 10;
k /= 10;
}
但是,您必须首先确定 k
的正确值(这取决于前导零是被忽略还是被反转 - 例如,如果 012 变为 210 或 021)。另请注意,这是昂贵的(循环内的除法、模数和乘法),这就是为什么您想尽一切可能避免这样做的原因。当然,如果数字范围足够小(例如,仅从 000 到 199 的值),那么您可以使用查找 table 来快速完成此操作。
虽然其他答案可以直接解决您的问题,但我想写一些关于该理论的内容,因为我认为它下次会对您有所帮助:
如你所写,十进制数1234在十六进制中写为4D2,4321在十六进制中写为10E1。
这意味着操作"reverting a number"在不同的数字系统中导致不同的结果:
在十进制系统中"reverting" 1234 导致4321。在十六进制系统中"reverting" 4D2 导致2D4。使用固定长度的 4 个十六进制数字(16 位寄存器!)但是 "reverting" 04D2 将导致 2D40...
如果某些操作只适用于特定的基数(*),您必须考虑以下几点:
使用使用字节的计算机,您可以轻松地在 base-256 中执行操作:xchg bh,bl
将 "revert" base-256 系统中数字的两位数。
可以使用移位和旋转以 2^N 为基数(例如二进制、八进制或十六进制)执行运算。
然而,在其他基数(例如十进制)上的操作您将需要计算个位数,执行操作并从数字计算(二进制)数。
为了恢复十进制数,以下伪代码可能有效:
A = input (here: 1234)
B = 0
mainLoop:
digit = A mod 10 (get the right digit of A)
A = A/10 (remove the right digit from A)
B = 10*B + digit (append the digit to B)
if A>0: jump to mainLoop
在汇编程序中,代码可能如下所示:
mov ax,1234 ; ax = "A" in the pseudo-code
mov cx,0 ; cx = "B" in the pseudo-code
mov bx,10 ; The base we are working in
mainLoop:
xchg ax,cx ; "mul" can only work with ax
mul bx ; Results: ax = "10*B"
; dx = overflow (typically 0)
xchg ax,cx ; Change ax and cx back: cx="10*B"
mov dx,0 ; Prepare dx for "div"
div bx ; Perform division and modulo
; Result:
; ax = "A/10"
; dx = "A MOD 10" = "digit"
add cx,dx ; "B = 10*B+digit"
cmp ax,0
ja mainLoop
; Here cx will contain the "reverted" number
(*) 您要执行的操作不是"reverting a number"而是"reverting a decimal number".
如何在字节级别反转寄存器值?
mov al,12 -----> how can i reverse al value
to 21
这是我尝试过的方法:
mov bx,4321 ;i want to make bx 1234
mov cl,04 ;cl for rotation value
xchg bh,bl ; now bx will 2143
mov al,bh ;moving 21 to al
rol al,cl ; rotate al 4 times to left now al is 12`
mov bh,al ; bh is 12 setuped ,time for bl
;---------------------------
mov al,bl ;moving lower byte 43 to al
rol al,cl ; rotate 4 times to left now al will 34
mov bl,al ; moving 34 to bl
现在bx
必须包含一个颠倒的数字1234;问题是数字是十六进制,即 10e1h 或 4321。
我倒过来是1e01h,但是这个值不是1234
1234 是 04d2。我得到的值是 7681d.
要反转字节中的位,请使用查找 table。要反转字中的位,请使用查找 table 反转最低 8 位,然后使用 rol ax,8
,然后使用查找 table 反转其他 8 位。
要反转一个字节中的(4 位)半字节,请使用 rol al,4
。要反转单词中的半字节,请使用 rol al,4; rol ax,8; rol al,4
.
用于反转字节或字中的十进制数字;不。相反,更改打印十进制数字的代码。原因是从整数(例如值 1234)到字符串(例如字符“1234”)的转换通常会以相反的顺序生成字符,并且必须做额外的工作来反转字符;所以 "print_reversed_decimal()" 会做更少的工作(并且以其他方式反转数字然后在打印时再次反转它是白费两倍的工作量!)。或者,您可以改用 BCD(每个半字节包含一个十进制数字)。在这种情况下,您可以使用 "reverse nibbles" 方法反转十进制数字,然后打印数字变得更便宜(移位和掩码而不是除法和模数)。
请注意,反转整数中十进制数字的数学运算类似于:
k = 10000000;
result = 0;
while(value > 0) {
digit = input % 10;
result += digit * k;
input /= 10;
k /= 10;
}
但是,您必须首先确定 k
的正确值(这取决于前导零是被忽略还是被反转 - 例如,如果 012 变为 210 或 021)。另请注意,这是昂贵的(循环内的除法、模数和乘法),这就是为什么您想尽一切可能避免这样做的原因。当然,如果数字范围足够小(例如,仅从 000 到 199 的值),那么您可以使用查找 table 来快速完成此操作。
虽然其他答案可以直接解决您的问题,但我想写一些关于该理论的内容,因为我认为它下次会对您有所帮助:
如你所写,十进制数1234在十六进制中写为4D2,4321在十六进制中写为10E1。
这意味着操作"reverting a number"在不同的数字系统中导致不同的结果:
在十进制系统中"reverting" 1234 导致4321。在十六进制系统中"reverting" 4D2 导致2D4。使用固定长度的 4 个十六进制数字(16 位寄存器!)但是 "reverting" 04D2 将导致 2D40...
如果某些操作只适用于特定的基数(*),您必须考虑以下几点:
使用使用字节的计算机,您可以轻松地在 base-256 中执行操作:xchg bh,bl
将 "revert" base-256 系统中数字的两位数。
可以使用移位和旋转以 2^N 为基数(例如二进制、八进制或十六进制)执行运算。
然而,在其他基数(例如十进制)上的操作您将需要计算个位数,执行操作并从数字计算(二进制)数。
为了恢复十进制数,以下伪代码可能有效:
A = input (here: 1234)
B = 0
mainLoop:
digit = A mod 10 (get the right digit of A)
A = A/10 (remove the right digit from A)
B = 10*B + digit (append the digit to B)
if A>0: jump to mainLoop
在汇编程序中,代码可能如下所示:
mov ax,1234 ; ax = "A" in the pseudo-code
mov cx,0 ; cx = "B" in the pseudo-code
mov bx,10 ; The base we are working in
mainLoop:
xchg ax,cx ; "mul" can only work with ax
mul bx ; Results: ax = "10*B"
; dx = overflow (typically 0)
xchg ax,cx ; Change ax and cx back: cx="10*B"
mov dx,0 ; Prepare dx for "div"
div bx ; Perform division and modulo
; Result:
; ax = "A/10"
; dx = "A MOD 10" = "digit"
add cx,dx ; "B = 10*B+digit"
cmp ax,0
ja mainLoop
; Here cx will contain the "reverted" number
(*) 您要执行的操作不是"reverting a number"而是"reverting a decimal number".