我是装配新手。我的任务是将八进制转换为十六进制,反之亦然。我只能在两个不同的 asm 文件中将八进制编码为二进制,然后将二进制编码为十六进制。现在我真的很想将它们合并在一起,以便我可以进行八进制到十六进制的转换。
这是两个代码:
.MODEL SMALL
.DATA
INP DB 0
MSG_1 DB "ENTER AN OCTAL NUMBER: $"
MSG_2 DB "BINARY VALUE OF THIS NUMBER: $"
.CODE
MAIN PROC
MOV AX,@DATA
MOV DS,AX
LEA DX,MSG_1
MOV AH,9
INT 21H
MOV SI,0
MOV AH,1
MOV CX,0
INPUT: INT 21H
MOV INP[SI],AL
INC CX
INC SI
CMP AL,13
JNE INPUT
CALL NEWLINE
CALL NEWLINE
LEA DX,MSG_2
MOV AH,9
INT 21H
MOV DI,0
MOV AH,2
DEC CX
OUTPUT: MOV BL,INP[DI]
CALL CONVERTOCT
INC DI
LOOP OUTPUT
MOV AH,4CH
INT 21H
ENDP
NEWLINE PROC
MOV AH,2
MOV DL,10
INT 21H
MOV DL,13
INT 21H
RET
NEWLINE ENDP
CONVERTOCT PROC
SUB BL,48
SHL BL,5
MOV DH,0
CONV:
SHL BL,1
JC PRINT1
JMP PRINT0
PRINT0:
MOV DL,'0'
INT 21H
INC DH
CMP DH,3
JE EXIT
JMP CONV
PRINT1:
MOV DL,'1'
INT 21H
INC DH
CMP DH,3
JE EXIT
JMP CONV
EXIT:
RET
CONVERTOCT ENDP
END
.MODEL SMALL
.STACK 100H
.DATA
MSG_1 DB "ENTER BINARY NUMBER: $"
MSG_2 DB "HEXADECIMAL OF THE NUMBER: $"
MSG_3 DB "INVALID! $"
.CODE
MAIN PROC
MOV AX,@DATA
MOV DS,AX
MOV AH,2
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H
MOV AH,9
LEA DX,MSG_1
INT 21H
XOR BH,BH
INPUT:
MOV AH,1
INT 21H
MOV CH,AL
CMP CH,0DH
JE PRINT
CMP CH,'0'
JL EXIT
CMP CH,'1'
JG EXIT
AND CH,15
SHL BH,1
OR BH,CH
JMP INPUT
PRINT:
MOV AH,2
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H
MOV AH,9
LEA DX,MSG_2
INT 21H
MOV AH,2
CMP BH,9
JLE NUMBER
CMP BH,15
JLE CHARACTER
NUMBER:
ADD BH,48
MOV AH,2
MOV DL,BH
INT 21H
MOV AH,4CH
INT 21H
CHARACTER:
ADD BH,55
MOV AH,2
MOV DL,BH
INT 21H
MOV AH,4CH
INT 21H
EXIT:
MOV AH,2
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H
MOV AH,9
LEA DX,MSG_3
INT 21H
MOV AH,4CH
INT 21H
MAIN ENDP
END MAIN
.DATA INP DB 0
您可能想先纠正此错误。您的 INP 输入缓冲区只有一个字节的空间!正确的写法是
INP db 6 dup (0)
,代表 5 个八进制数字和回车符。
首先选择一个可用的寄存器作为您将输入的八进制数字的累加器。选择
BP
寄存器允许处理最多 5 个八进制数字。CONVERTOCT PROC
push cx
mov cl, 5 ; 8086 didn't have shift by immediate, and so should emu8086!
shl bl, cl ; The conversion happens for free via this shift left
CONV:
shl bl, 1 ; Out at the top
rcl BP, 1 ; In at the bottom
sub cl, 2 ; 3 iterations
jnb CONV
pop cx
ret
CONVERTOCT ENDP
您的第二个程序(表示它可以打印十六进制),期望其输入为
BH
。修改 that 代码,以便它可以使用 BP
寄存器中的值,或者将您的目标降低到 2 个八进制数字,然后从 BP
转换为 BH
:
mov bx, BP
mov bh, bl
接下来是更完整的代码。输入的八进制数字不存储在内存中。输入得到验证,并且转换随着输入的进行而完成:
; Input octal digits up to the max value 177777o
; You can use as many leading zeroes as you like!
xor bx, bx ; The resulting number
MoreInput:
mov ah, 01h
int 21h ; -> AL
cmp al, 13
je GotIt
sub al, "0" ; From ["0","7"] -> [0,7] ?
cmp al, 8
jnb MoreInput ; Redo because it was not an octal digit
mov cl, 5 ; 8086 didn't have shift by immediate!
shl al, cl ; From 00000xxx to xxx00000
Convert:
shl al, 1 ; Out at the top
rcl bx, 1 ; In at the bottom
jc Overflow ; TO BE DECIDED WHAT THIS NEEDS TO DO
sub cl, 2 ; 3 iterations
jnb Convert
jmp MoreInput
GotIt:
下面的代码现在以十六进制表示形式打印 BX 的内容:
mov cx, 0404h ; CH counts hex digits, CL counts rotations
MoreOutput:
rol bx, cl ; 8086 didn't have rotate by immediate!
mov dl, bl
and dl, 15
add dl, "0"
cmp dl, "9"
jbe Print
add dl, 7 ; -> ["A","F"]
Print:
mov ah, 02h
int 21h
dec ch
jnz MoreOutput