輸入乙個最大長度為4的十六進製制數,將其轉換成10進製輸出。
其中我們需要檢測十六進製制輸入的正確性,比如大小寫、特殊字元和數字的判斷。
程式分為兩個部分,首先是處理我們的輸入,以及通過除法計算十進位制數的過程。
data segment use16
data ends
stack segment use16
db 32
dup(?)
stack ends
code segment use16
assume cs:code, ds:data, ss:stack
main proc
start:
mov ax,data
mov ds,ax
xor bx,bx
mov dl,
4 loop1:
cmp dl,
0 jz next
mov ah,
1int
21h cmp al,
13 jz next
;數字cmp al,
30h jb loop1
cmp al,
39h ja big
sub al,
30h dec dl
jmp fin
big:
cmp al,
65 jb loop1
cmp al,
70 ja small
sub al,
37h dec dl
jmp fin
small:
cmp al,
97 jb loop1
cmp al,
102 ja loop1
sub al,
87 dec dl
fin:
mov cl,
4 shl bx,cl
and ax,
0fh add bx,ax
jmp loop1
next:
cmp dl,
0 jnz no_need
mov dl,
10 mov ah,
2int
21h mov dl,
13 mov ah,
2int
21h no_need:
mov ax,bx
mov cx,
10 xor bx,bx
turn_in:
xor dx,dx
div cx
push dx
inc bl
cmp ax,
0 jz turn_out
jmp turn_in
turn_out:
pop dx
add dl,
30h mov ah,
2int
21h dec bl
cmp bl,
0 jnz turn_out
mov ah,
4ch int
21hmain endp
code ends
end start
輸入(next標號之前)
首先看一下輸入部分,我們需要解決四個問題。
首先,我們將dl作為計數器,每一次迴圈觀測dl是否為0,同時讀入乙個資料,判斷是否為回車(ascii為13)。
然後我們判斷一下輸入的正確性問題。這裡我畫出了ascii表中數字和大小寫的排列順序。
所以我們是這樣判斷的:
這就是我們的跳轉流程。
(為什麼要減這些數,自己查一下ascii,當增強記憶了)
與其說這個結構是if_else,我倒是感覺更像case,其中的jmp指令就像是break,如果沒有break,那麼我們就會將下乙個分支也執行了,導致出錯。
在每一次讀入之後,我們說白了其實是將之前的作為高位,然後加入低位。
(比如輸入十進位制123,我們是先將12左移一位,也就是乘十,然後加三)
這裡也一樣,不過我們需要bx右移四位(暫存器中為二進位制數),然後加上儲存在al的值。
另外附上我們的測試案例:(1e23),可以看到bx值正確。
輸出這裡因為是十進位制的輸出,我們之前還可以通過進製偷懶(指輸出二進位制或十六進製制數),現在是不行了。
這裡我們採用每一次除以10,將餘數壓棧的方式,儲存好結果的相反順序,然後pop到dl,進行輸出。
這裡先講一下彙編的乘除法吧。
對於兩個二進位制數來說,a位乘以b位的,那麼結果一定不會大於a+b位。
(2a-1-1和2b-1-1一定小於2a+b-1)
我們在除的過程中也是如此,因為bx是16位,我們的除數10為4位,所以我們的結果是不能用al和ah放下的(餘數小於等於除數的位數,商小於等於被除數字數減除數字數。)
那麼我們還有一種辦法,就是將dx:ax作為被除數,將cx作為除數,這樣商在ax,餘數在dx,就能放下了。
如果是再次除,我們只需要將dx置零。
效果:
通過這樣乙個案例,我們知道了選擇除法範圍也是有考量的,不是怎麼方便怎麼來的。
turn_in迴圈就實現了每一次將ax暫存器除以十,商在ax,餘數在dx,將dx壓棧後清零,再次進行除法。
每一次除法我們都將計數器bl自增,方便出棧使用。
當ax暫存器為0,我們結束迴圈,進入到輸入(turn_out)部分。
turn_out部分我們每乙個迴圈都彈出乙個dx,因為dx的餘數一定是小於10的,我們直接加30h輸出即可。
這裡寫的不是太好,其實完全可以將bl放在cl中,然後直接loop的。
這部分最重要應該就是跳轉邏輯和我們的除法部分。
另外講解一下no_need標籤部分:
因為我們如果是輸入滿四位,會強制性結束輸入,這時就沒有我們的回車顯示了,所以我加了乙個判斷來進行換行,看著比較舒服,沒別的意思。
然後補充一下自己的十進位制輸入轉二進位制/十六進製制輸出的案例。
十進位制 十六進製制
把十進位制整數轉換為十六進製制,格式為0x開頭,10 15由大寫字母a f表示。input 每行乙個整數x,0 x 2 31。output 每行輸出對應的八位十六進製制整數,包括前導0。sample input 0 1023 sample output 0x00000000 0x000003ff 水...
十進位制轉十六進製制(進製轉換)
問題描述 十六進製制數是在程式設計時經常要使用到的一種整數的表示方式。它有0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f共16個符號,分別表示十進位制數的0至15。十六進製制的計數方法是滿16進1,所以十進位制數16在十六進製制中是10,而十進位制的17在十六進製制中是11,以此類推...
十進位制 十六進製制轉換 javascript實現
十進位制整數轉成十六進製制數 輸入 dec 十進位制整數 輸出hex 返回 0x 開頭的轉換後的字串 原理 十進位制數通過 位操作轉換成二進位制,然後通過4bit取出為十六進製制。例如 dec 40000,二進位制是 1001110001000000 先轉換成 0x04c9 然後倒序轉換成十六進製制...