[英]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。
雖然其他答案可以直接解決您的問題,但我想寫一些關於該理論的內容,因為我認為它下次會對您有所幫助:
正如您已經寫過的,十進制數 1234 在十六進制中寫為 4D2,而 4321 在十六進制中寫為 10E1。
這意味着“還原數字”操作在不同的數字系統中會導致不同的結果:
在十進制系統中,“還原”1234 導致 4321。在十六進制系統中,“還原”4D2 導致 2D4。 使用固定長度的 4 個十六進制數字(16 位寄存器)。但是“還原”04D2 將導致 2D40...
如果某些操作僅適用於特定基數 (*),則必須考慮以下事項:
使用處理字節的計算機,您可以輕松地在 base-256 中執行操作: xchg bh,bl
將“還原”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
(*) 您要執行的操作不是“還原數字”,而是“還原十進制數”。
要反轉字節中的位,請使用查找表。 要反轉字中的位,請使用查找表反轉最低 8 位,然后rol ax,8
,然后使用查找表反轉其他 8 位。
要反轉字節中的(4 位)半字節,請使用rol al,4
。 要反轉單詞中的半字節,請使用rol al,4; rol ax,8; rol al,4
rol al,4; rol ax,8; rol al,4
rol al,4; rol ax,8; rol al,4
。
用於反轉字節或字中的十進制數字; 不。 相反,更改打印十進制數字的代碼。 原因是從整數(例如值 1234)到字符串(例如字符“1234”)的轉換通常會以相反的順序生成字符,並且必須做額外的工作來反轉字符; 所以“print_reversed_decimal()”會做更少的工作(並且以其他方式反轉數字然后在打印時再次反轉它是白費兩倍的工作量。)。 或者,您可以改用 BCD(其中每個半字節包含一個十進制數字),在這種情況下,您可以使用“反向半字節”方法反轉十進制數字。 之后打印數字變得更便宜(移位和掩碼而不是除法和模數)。
請注意,反轉整數中的十進制數字的數學運算類似於:
k = 10000000;
result = 0;
while(value > 0) {
digit = input % 10;
result += digit * k;
input /= 10;
k /= 10;
}
但是,您必須首先確定k
的正確值(這取決於前導零是被忽略還是被反轉——例如,如果 012 變為 210 或 021)。 另請注意,這是昂貴的(循環內的除法、模數和乘法),這就是為什么您想盡一切可能避免這樣做的原因。 當然,如果數字范圍足夠小(例如僅從 000 到 199 的值),那么您可以使用查找表來快速完成此操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.