彙編 十六進製制輸入轉換十進位制輸出(附加輸入檢測)

2021-10-14 01:47:55 字數 3723 閱讀 6081

輸入乙個最大長度為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 然後倒序轉換成十六進製制...