1、二进制转十六进制
这段汇编代码的主要功能是将寄存器BX中的16位数逐位按照十六进制逆时针旋转一圈(4位),并将结果打印在屏幕上,输出结果的形式为16进制数字。整个过程通过循环、移位、比较、加减来实现
1、
;这段代码的功能:将BX中的16位数逐位按照十六进制逆时针旋转一圈(4位),并将结果打印出来
mov ch, 4 ; 设置循环计数器CH的初值为4,循环4次
rotate:
mov cl, 4 ; 设置移位操作数CL的值为4
rol bx, cl ; 将BX左移4位,移到最高位到最低位,并将CF标志设置为所移出的最高位
mov al, bl ; 将BX的低8位复制到AL
and al, 0fh ; 将AL的高四位清零,只保留低四位的值(先将16进制数的最高位数值抠出来)
add al, 30h ; 将AL的值加上ASCII码‘0’(30h),将数字变成字符
cmp al, 3ah ; 判断AL是否大于ASCII码‘9’(39h),即是否是数字字符外的字符
jl printit ; 如果AL小于‘:’(3ah),即是数字字符,则跳转到printit标记
add al, 7h ; 如果AL大于等于‘:’,即是字母字符,将AL的值加上‘7’,转换成字母字符
printit: ; 输出结果标记
mov dl, al ; 将结果存储在DL中,好输出
mov ah, 2 ; 设置功能号为2,表示输出一个字符
int 21h ; 调用21h中断,输出字符
dec ch ; 循环计数器减1
jnz rotate ; 如果计数器不为0,继续循环
2、编一个程序完成从键盘上输入一个16位以内(回车结束)的二进制数,并以16进制形式显示出来(大同小异)
.model small
.stack 100h
.data
string db 17,?,17 dup(' ');输入16位以内
newline db 0ah,0dh,'$'
N DW 0
.code
start:
mov ax,@data
mov ds,ax
qishi:
lea dx,string
mov ah,0ah
int 21h
lea dx,newline
mov ah,09h
int 21h
lea si,string+1;输入的位数
mov cl,[si]
mov ch,0
L:
add si,1
mov al,[si]
sub al,30h
cmp al,0;保证输入的二进制是0或1
jl qishi
cmp al,1
jg qishi
mov bl,al ;al的值有两处存储。bl:当前输入的一位,N:过去输入的二进制
mov bh,0
mov ax,N ;AX!
shl ax,1
add ax,bx
mov N,ax
LOOP L
mov ax,N
mov ch,4 ;每次4位,循环ch=4次
;每4位转16进制
L2: mov cl,4
rol ax,cl ;最高位移动到最低位
push ax ;移动后保存,方便下一次
and al,0fh
mov dl,al
add dl,30h
cmp dl,39h
jle L3
add dl,07h
L3: mov ah,02h
int 21h
pop ax
dec ch ;下一个4位
cmp ch,0
jne L2
mov ah,4ch
int 21h
end start
2、 二进制转十进制
首先将二进制数补齐位数,首位如果是0就代表正整数,首位如果是1就代表负整数。
若首位是0的正整数,补齐位数以后,将二进制中的位数分别与对应的值相乘,然后相加得到的就为十进制。(从后往前数位数,从0开始数)
***判断JS输出负号!数字输出要add dl,30h
1、下面程序输入16位以内的二进制数(输入时回车作为输入结束),然后以有符号十进制数形式显示出来。将空格处指令补充完整,使得程序能完整实现所需要的功能。
CODE SEGMENT
ORG 100H
ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE
MAIN PROC NEAR
CALL I2;输入二进制
CALL D10;输出十进制
MOV AH,4CH
INT 21H
MAIN ENDP
I2 PROC NEAR
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
XOR BX,BX
MOV CX,16;输入16位数
L20: MOV AH,1
INT 21H
(CMP AL,0DH )……………①;回车
JE L21
CMP AL,30H;接收01
JB L20
CMP AL,31H
JA L20
AND AX,01H;清除高八位
SHL BX,1
ADD BX,AX
( LOOP L20 )……………②;循环输入16个数
L21: MOV AX,BX;输入的二进制
POP DI
POP SI
POP DX
POP CX
POP BX
RET
I2 ENDP
D10 PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
( MOV BX,AX )……………③
MOV AH,9
LEA DX,CRLF
INT 21H
OR BX,BX;是否负数
JNS L100;非负数跳转
MOV AH,2
mov dl,2dh )……………④;输出负号
INT 21H
NEG BX
L100: MOV AX,BX
XOR CX,CX
MOV SI,10
L101: XOR DX,DX
( DIV SI )……………⑤;将AX除以10,商在AX中,余数在DX中
PUSH DX;将余数压栈
INC CX;将CX寄存器加1(记录位数)
CMP AX,0;获取商的值
JNZ L101
L102: POP DX;将栈顶元素弹出到DX寄存器
MOV AH,2
( ADD DL,30H )……………⑥;将数字转换成字符
INT 21H
LOOP L102
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
( RET )……………⑦
CRLF DB 0DH,0AH,24H
D10 ENDP
CODE ENDS
END MAIN
3、二进制转八进制
编写一个程序,从键盘输入一个不大于16位的2进制数,然后以8进制形式显示出所输入的数
DATA SEGMENT
x dw 0ah,0dh,'$'
InputBuffer db 17,0,17 dup (0)
UserInput dw 0
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:
MOV AX,DATA
MOV DS,AX
call GetUserInput ;输入子程序
mov UserInput,ax ;取得输入值16进制,也是2进制
lea dx,x
mov ah,9
int 21h
mov bx,UserInput ;取得输入值
mov cl,3 ;移位数
mov ch,0 ;计数
next:
mov ax,bx
and ax,0000000000000111b ;取低3(111)位,即八进位
or al,'0' ;转ascii
push ax ;保存
inc ch ;计数
shr bx,cl ;左移3位,即下一位
or bx,bx ;是否完了
jnz next ;未
mov cl,ch ;取得计数
mov ch,0 ;清0
next1:
pop dx ;弹出dl
mov ah,2 ;印出结果
int 21h
loop next1
mov ah,7 ;暂停
int 21h
quit:
MOV AH,4CH ;带返回码结束功能
INT 21H ;返回系统
;-----------------------
GetUserInput:
mov dx,offset InputBuffer ;指向输出缓冲
mov ax,0c0ah ;输入函数,先清空键盘缓冲
int 21h
mov si,offset InputBuffer + 2
mov cx,0
mov cl,[si-1] ;取实际输入数
jcxz GetUserInput ;无输入
Call GetValue ;取值子程序,ax传回该值,cf=1表示错误,可能输入非数字
jc GetUserInput ;输入错误,非数字
ret
;--------------------------------------------------------------------------
;转值子程序,把输入的字符转成16进制(2进制)
;输入:ds:si数字字符串起点,以0dh结束
;输出:ax=转换后的16进制值,cf=1表示有非数字字符
GetValue:
push bx
push di
xor bx,bx
mov di,10
GetV10:
lodsb ;指向起点
mov ah,0 ;清除
cmp al,0dh ;回车?
jz Getvx
cmp al,'0' ;以下比较0-1,否则cf=1离开
jb Getvy
cmp al,'1'
ja Getvy
sub al,'0' ;ascii -> 值
shr al,1 ; cf=1,1 cf=0,0
rcl bx,1 ;一位接一位的旋入bx
jmp short GetV10
Getvx: mov ax,bx ;ascii转值后由ax转回
clc ;成功cf=0
jmp short Getvz
Getvy:
stc ;错误 cf=1
Getvz:
pop di
pop bx
ret
;------------------------------------
CODE ENDS
END START
4、十进制转十六进制
短除法,余数为十六进制数字表达(10~15转化为字母),商继续除以16,直到商等于0为止。
以十进制的形式输入,以16进制形式输出
P SEGMENT
ORG 100H
ASSUME CS:P,DS:P,ES:P,SS:P
MAIN PROC NEAR
XOR BX,BX
L1: MOV AH,1
INT 21H
CMP AL,0DH
JE L2
CMP AL,30H
JB L1
CMP AL,39H
JA L1
AND AX,0FH
;将用户输入的十进制数字转换为二进制数字后,
需要将其存储在二进制格式的数据结构中,
在此过程中,需要将每一位十进制数字乘以适当的权值,
即10的幂,然后将不同位的结果相加
XCHG AX,BX
MOV CX,10
MUL CX
JC L5;如果结果不能放在AX中,则跳转到L5
ADD BX,AX
JC L5;会发生进位,因此通过进位标志CF来检测是否发生了进位。
JMP L1
L2: MOV AH,2
MOV DL,0DH
INT 21H
MOV AH,2
MOV DL,0AH
INT 21H
;开始十六进制输出
MOV CX,4;将CX设置为4(表示输出4位十六进制数)
L3: PUSH CX
MOV CL,4; 将CL寄存器的值设置为4(表示隔离下四位)
ROL BX,CL;将BX的二进制码向左旋转4位(使下四位成为最高位)
MOV DL,BL
AND DL,0FH;隔离最低的4位
ADD DL,30H
CMP DL,39H
JBE L4
ADD DL,7
L4: MOV AH,2
INT 21H
POP CX
LOOP L3; 循环CX次
JMP L6
L5: MOV AH,9
LEA DX,ERROR
INT 21H
L6: MOV AH,4CH
INT 21H
ERROR DB 0DH,0AH,"OVERFLOW",07,0DH,0AH,24H
MAIN ENDP
P ENDS
END MAIN
2、编写一个程序,从键盘输入一个0~65535之间的10进制无符号数,然后以16进制形式显示出所输入的数。
data segment
string db 0dh
num db 4 dup(?),'H$'
tab db '0123456789ABCDEF'
data ends
code segment
assume cs:code,ds:data
begin: mov ax,data
mov ds,ax ;初始化代码段
xor bx,bx
mov cx,10 ;进制
next: mov ah,1
int 21h
cmp al,0dh
jz conv ;如果是回车,表示输入结束,转换开始
push ax ;保存输入值,当然还有AH,因为堆栈的存取必须以字为单位
mov ax,bx
mul cx
mov bx,ax ;将先前的结果向上推一位
pop ax ;取回本次输入
and al,0fh ;屏蔽掉无用位,类SUB AL,30H
xor ah,ah ;高位归零
add bx,ax ;合并本次输入
jmp next
conv: mov ax,bx ;开始转换
mov ch,4
lea bx,tab ;bx直接定址表
mov cl,4
lea si,num
lopa: rol ax,cl ;把高4位移到低4位
push ax
and ax,000fh ;取出低4位
xlat
mov [si],al ;按地址由低到高的顺序将结果由高到底存放
inc si
pop ax
dec ch
jnz lopa
lea dx,string
mov ah,9
int 21h ;回车换行
mov ah,4ch
int 21h
code ends
end begin
5、十六进制转十进制
十六进制转换成十进制的公式是:要从右到左用二进制的每个数去乘以16的相应次方,然后这些数字相加就是了。
下面是一个.com文件格式的程序,完成从键盘上输入一个4位以内的16进制数,并以10进制形式显示出来。请在标号处填上缺少的指令(TEST1)
HEX2DEC SEGMENT
ORG 100H
ASSUME CS:HEX2DEC,SS:HEX2DEC,DS:HEX2DEC,ES:HEX2DEC
MAIN PROC NEAR
XOR BX,BX;清零,将存储转换后的十进制
MOV CH,4;循环次数(输入4位以内)
L1: MOV AH,1;键盘输入并回显
_____(1)_______INT 21H
CMP AL,0DH;是否为回车
JE DISP10
CMP AL,30H;是否<0
JB L1;
______(2)_______CMP AL,39H;是否>9
JBE L2;0-9为合法数字
CMP AL,41H;是否字母
JB L1;非法字符,重新输入
CMP AL,46H
JBE L2;A-F
CMP AL,61H;是否小写字母
JB L1
CMP AL,66H
JA L1
SUB AL,20H;小写字母转换为大写
L2: SUB AL,30H;转换为对应的十进制数字
CMP AL,9
JBE L3;0-9数字
SUB AL,7;10-15字母转换
L3: MOV CL,4;循环
SHL BX,CL;为下个位的处理腾出空间
XOR AH,AH;防止移位溢出
ADD BX,AX;转换后的10进制数存储
____(3)_________ DEC CH;处理下个字符前,循环计数器CH-1
JNZ L1
DISP10: LEA DX,CRLF
MOV AH,9;显示回车
INT 21H
OR BX,BX;判断是否小于0
JNS L4;不小于0时
MOV DL,2DH;负数,将“-”存储
MOV AH,2
INT 21H
NEG BX;取反,把负数变正数
;;准备十进制数输出显示操作
L4: XOR CX,CX;记录10进制数位数,初始化为0
MOV AX,BX;10进制数存储
L5: XOR DX,DX;存储被除数的余数
____(4)________ MOV SI,10
DIV SI;把AX数除以10,商放AL,余数在DX
PUSH DX
INC CX;每除1次,代表位数+1
OR AX,AX;若商为0,准备输出
JZ L6
JMP L5
L6: POP DX;后进先出(高位)
____(5)___________ADD DL,30H;转ASCII
MOV AH,2
INT 21H
LOOP L6
INT 20H;程序正常结束
CRLF DB 0DH,0AH,24H;回车换行符加字符串结束符号’$’
MAIN ENDP
HEX2DEC ENDS
END MAIN
6、十六进制转八进制
编一个程序完成从键盘上输入一个4位的16进制数,并以八进制形式显示出来。
Data segment
Strlen db 5
Actlen db ?
String db 5 dup(?)
Data ends
Code segment
assume ds:Data, cs:Code
start:
mov ax,Data
mov ds,ax
lea dx,strlen
mov ah,10
int 21h ;输入16进制数
mov ah,2
mov dl,0dh
int 21h
mov dl,0ah
int 21h ;输出回车换行
mov ch,0
mov cl,actlen
lea si,string
mov bx,0
l:
push cx
mov dl,[si]
cmp dl,'a'
jb next1
sub dl,20h ;小写变大写
next1:
cmp dl,'A'
jb next2
sub dl,7 ;为大写字母变为相应的数值做准备
next2:
sub dl,30h ;变为所相对应的数值
mov dh,0
mov cl,4
shl bx,cl ;4个16进制数刚好可以存放到一个字,在这里存放到bx
add bx,dx ;依次推入到bx中
inc si
pop cx
loop l
mov ax,bx ;以8进制形式输出
mov bx,8
mov cx,0
ldiv:
mov dx,0
div bx
push dx
inc cx
cmp ax,0
jz toPrint
jmp ldiv
toPrint:
pop dx
add dl,30h
mov ah,2
int 21h
loop toPrint
mov ah,4ch
int 21h
Code ends
end start
7、十进制转二进制
data segment
buf db 0ah,0dh,'please input decimal number:$' ; 提示用户输入十进制数的信息
b_x db 10 ; 十进制数转换为二进制时的基数
data ends
stack segment
db 128 dup(0)
stack ends
code segment
assume cs:code, ds:data, ss:stack
start:
mov ax, data
mov ds, ax ; 设置数据段寄存器
lea dx, buf
mov ah, 9
int 21h ; 显示提示信息
mov bx, 0 ; bx 寄存器用于存储转换结果
mov ax, 0 ; ax 寄存器用于读取用户输入的字符
input:
mov ah, 1
int 21h ; 读取用户输入的字符
cmp al, 0dh ; 检查是否输入了回车键
jz binary1
cmp al, 1bh ; 检查是否用户想要退出
je exit1
and al, 0fh ; 将输入的字符转换为数值
cbw ; 将 al 的无符号字节扩展到 ax
xchg ax, bx ; 将 bx 中的结果与当前输入的数值进行交换
mul b_x ; 将 bx 中的结果乘以 10(十进制基数)
add bx, ax ; 将输入的数值加到 bx 中
jmp input
binary1:
mov ah, 2
mov dl, 0ah
int 21h ; 换行显示二进制数的提示信息
mov cx, 16 ; cx 寄存器用于循环计数
disp:
mov dl, 0
rol bx, 1 ; 循环左移 bx 寄存器中的结果
rcl dl, 1 ; 循环左移 dl 寄存器中的结果
or dl, 30h ; 将结果转换为 ASCII 数字字符
mov ah, 02h
int 21h ; 显示二进制数的每一位
loop disp ; 循环显示所有位
mov dl, 'B'
mov ah, 02h
int 21h ; 显示二进制数后的标识 "B"
exit1:
mov ah, 4ch
int 21h ; 退出程序
code ends
end start