汇编进制转化总结|二进制,十进制,十六进制及带符号数输入输出总结

汇编进制转化总结


10、2进制无符号输入
  • 如果是10进制,把n值改成10即可
  • 如果是2进制,把n值改成2即可
DATAS SEGMENT
    x dw ?
    n dw 10   ;规定进制数,这里是10进制。如果是2进制,改成2即可。
DATAS ENDS
STACKS SEGMENT	stack
      db 100h dup(?)
STACKS ENDS
CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
     mov bx,0  ;bx作为一个累加存储作用
L1:;循环输入
	mov ah,1   ;1号调用,输入一个字符
	int 21h  
	cmp al,0dh  ;回车就跳出
	jz  l2
	sub al,30h  ;减30h,让数字字符成为数字
	mov ah,0
	xchg bx,ax
	mul n       ;乘以10
	            ;如果是2进制,可以用逻辑左移!
	add bx,ax   ;再加上新输入进来的
	jmp l1
L2: 
	mov x,bx
    MOV AH,4CH
    INT 21H
CODES ENDS
    END START

10、2进制无符号输出
  • 如果是10进制,把b值改成10000,1000,100,10,1即可
  • 如果是2进制,把b值改成64,32,16,8,4,2,1即可
  • cx控制位数。注意要跟着变。
.model small
.data
	x	dw	123
	b	dw 	10000,1000,100,10,1 ;最高支持5位数的输出,而且是10进制的。
	flag db 0                   ;如果是2进制,则改成 32,16,8,4,2,1
.stack 100h
.code	
start:	mov	ax,@data
	mov	ds,ax
	mov	ax,x  ;把输出的数放在ax中
	mov	bx,offset b   ;把进制控制放在bx中
	mov	flag,0        ;控制0要不要输出
	mov	cx,5          ;5位数的输出
r1:	mov	dx,0          ;dx ax / bx, 因此要dx置零
	div	word ptr [bx]
	mov	si,dx         ;保存余数
	cmp	ax,0          ;看结果是否为零
	jz	r2            ;是
	mov	flag,1        ;如果不是零,则下一个数为0时,可以输出
r2:	cmp	flag,0        ;看可不可以输出
	jz	r3            ;flag为0,代表到目前为此,还没有出现不是0的数,因此不输出
	mov	dl,al        ;否则,进行输出
	add	dl,30h
	mov ah,2
	int	21h
;r3的作用是更新循环条件
r3:	add	bx,2  ;注意,这里一定是加2!!!!!因为是 dw 定义的!!!!
	mov	ax,si   ;把保存的余数放回ax中
loop r1
	mov	ah,4ch
	int	21h
	end	start

经典例题

包含的两段子程序有两种功能:

  • 第一个是2进制的输入
  • 第二个是带符号的10进制的输出。而且采用的是求模取余法。
;下面程序输入16位以内的二进制数(输入时回车作为输入结束),然后以有符号十进制数形式显示出来。将空格处指令补充完整,使得程序能完整实现所需要的功能。
DATA	segment
CRLF    	DB	0DH,0AH,24H
DATA	ends
CODE	SEGMENT
    	
ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE

MAIN	PROC   NEAR
	mov 	ax,data
	mov 	ds,ax
      	CALL   I2
      	CALL   D10
	    mov ah,9cH ;返回dos系统           )……………① 
       	INT	21H
MAIN	ENDP
;I2 ----------------------------------------------------------------------
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    ;如果小于0,则退出
       	JB     L20
       	CMP    AL,31H    ;如果大于1,则退出
       	JA     L20
       	AND    AX,01H     ;因为数字0的ascill码是30H,数字1的ascill码是31H,与上一个01H,可以把最低位的数字取出来
        SHL    BX,1       ;逻辑左移,相当于乘以2
        ADD    BX,AX      ;累加
       loop L20       ;循环输入      )……………③ 
       
L21:  	    MOV    AX,BX
        	POP    DI
        	POP    SI
        	POP    DX
        	POP    CX
    	    POP    BX ;还原现场           )……………④ 
        	RET
I2      	ENDP
;I2 ends ----------------------------------------------------------------------

D10     	PROC   NEAR
        	PUSH   AX
        	PUSH   BX
        	PUSH   CX
        	PUSH   DX
        	PUSH   SI
        	PUSH   DI
            mov bx, ax ;可以看到,下面的操作都是操作bx的。说明数存在bx中   )……………⑤
                      ;为什么放在bx中?可以看到调用dos调用,要用到ax
        	MOV    AH,9
        	LEA    DX,CRLF   ;输出换行回车
        	INT    21H
            OR     BX,BX     ;自己异或自己,虽然不改变数值,但改变标志位
        	JNS    L100      ;如果符号位不是1(即正数)
        	MOV    AH,2
        	mov 	dl,"-"   ;是负数,先输出负号
        	INT    21H
        	NEG    BX     ;如果是负数,求补,成为正数!!!!
L100:   	MOV    AX,BX  ;把数放回ax中,因为要作除法了
        	XOR    CX,CX  ;清零
        	MOV    SI,10  ;进制的控制!!!如果是2进制,改成2 即可
L101:   	XOR    DX,DX  ;dx清零,因为要 dx,ax / si 了
        	div    si    ;除以进制               )……………⑦ 
        	PUSH   DX    ;把余数压栈
        	INC    CX    ;统计进栈的数的数量
        	CMP    AX,0
        	JNZ    L101  ;如果ax还没有到0,要继续循环
L102:   	POP    DX
        	MOV    AH,2
        	dec    cx   ; 保证循环正常结束               )……………⑧ 
        	INT    21H
        LOOP   L102
		    POP    DI
        	POP    SI
        	POP    DX
        	POP    CX
        	POP    BX
        	POP    AX
        	RET
D10     	ENDP

CODE    	ENDS
        	END     MAIN

16进制无符号输入
DATAS SEGMENT
    x dw ?
    n dw 16   ;规定进制数,这里是16进制
DATAS ENDS
STACKS SEGMENT	stack
      db 100h dup(?)
STACKS ENDS
CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
     mov bx,0  ;bx作为一个累加存储作用
L1:;循环输入
	mov ah,1   ;1号调用,输入一个字符
	int 21h  
	cmp al,0dh  ;回车就跳出
	jz  L2
	
	cmp al,39H
	ja upperThanNine        
lowerThanNine:
 			sub al,30h  ;减30h,让0~9数字字符成为数字
 			jmp calcu
upperThanNine:
			sub al,37H ;让字母A~F转化为数字	
calcu:
    mov ah,0
	xchg bx,ax
	mul n       ;乘以16
	add bx,ax   ;再加上新输入进来的
	jmp L1     ;循环输入
L2: 
	mov x,bx
    MOV AH,4CH
    INT 21H
CODES ENDS
    END START

16进制无符号输出
DATAS SEGMENT
;用查表的方法来做
	nums db 30H,31H,32H,33H,34H,35H,36H,37H,38H,39H,41H,42H,43H,44H,45H,46H
	x dw 12  ;要输出的数
DATAS ENDS

STACKS SEGMENT
    ;此处输入堆栈段代码
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
    ;此处输入代码段代码
 
    MOV CX,0 ;计算有多少个数在栈里面
	MOV AX,X ;要输出的数
	MOV BX,16  ;进制是16
L1:
    MOV DX,0   ;因为 Dx,ax / bx , 所以dx清零
    DIV BX
    PUSH DX    ;余数入栈
    INC CX    ;统计多少个数在栈里面
    CMP AX,0
    JZ OUTPUT  ;如果是为0,则输出
    jmp L1
    
OUTPUT:
	POP SI
	MOV DL,nums[SI] ;查表,把数字转化成字符
	MOV AH,2
	INT 21h
	LOOP OUTPUT
    
    MOV AH,4CH
    INT 21H
CODES ENDS
    END START
带符号数的输入输出
DATAS 	SEGMENT
	A	dw ?
    B 	dw	?
    X	dw	?
    ERR	DB	'Input	Error!$'
	ENT	DB	0DH,0AH,24H 
DATAS	 ENDS

STACKS  	SEGMENT STACK
    DB 100H DUP(?)
STACKS  	ENDS

CODES 	SEGMENT
    ASSUME 	CS:CODES,DS:DATAS,SS:STACKS
MAIN	PROC	
START:
    	MOV 	AX,DATAS
    	MOV 	DS,AX
		CALL	INNUM 
		MOV 	X,AX  ;AX是INNUM子程序最终的输入结果
		CALL	ENTER1  ;输出换行回车。因为这里要用到dos调用,所以用X作为暂存
		MOV 	AX,X
		CALL    OUTNUM
	   
   		MOV AH,4CH
    	INT 21H
MAIN ENDP

INNUM	PROC
		MOV	B,0     ;B作为累和的存储
		MOV	A,0	    ;A记录符号位
BIN:	MOV	AH,1
		INT	21H
		CMP	AL,0DH  
		JZ	EXIT   	;回车跳出
		CMP	AL,2DH  ;2DH 是 “-” 负号
		JNZ	GO
		MOV	A,1     ;如果是负号,则A置为1
	JMP	BIN     ;循环输入
GO:	    CMP	AL,30H
		JB	ERROR
		CMP	AL,39H
		JA	ERROR   ;不在0~9的,都报错
		MOV	BL,10   ;BL代表进制,这里是10进制
		XOR	BH,BH   ;BH清零,因为
		SUB	AL,30H  ;让符号成为数字
		XOR	AH,AH   ;AH清零,因为接下来要把AX压栈
		PUSH	AX  ;AX压栈,因为接下来要用最后的累和数作乘法
		MOV	AX,B    ;把最后的累积数送往AX
		MUL	BL      ;乘以进制
		MOV	B,AX    
		POP	AX
		ADD	B,AX
	JMP	BIN     ;循环输入
ERROR:	CALL	ENTER1
		LEA	DX,ERR
		MOV	AH,9
		INT	21H
		RET	
		
EXIT:	CMP	A,0  
		JZ	NOTE ;如果是正数,直接把最终结果给AX即可
		NEG	B    ;如果是负数,则对B求补
NOTE:	MOV	AX,B
		RET
INNUM	ENDP

;------------------------
; 输出回车换行
;------------------------	
ENTER1	PROC	
		LEA	DX,ENT
		MOV	AH,9
		INT	21H
		RET
ENTER1	ENDP

;------------------------
; 输出一个数字,入口参数AX
;------------------------
;用的是求模取余法
OUTNUM	PROC
		CMP	AX,0
		JGE	L0   ;如果数>=0, 非负
		NEG	AX   ;如果是负数,先求补
		PUSH	AX
		MOV	DL,'-'  ;输出负号
		MOV	AH,2
		INT	21H
		POP	AX	
L0:		MOV	CX,0
L1:		MOV	DX,0   ;因为要 DX,AX / BX, 所以DX要清零
		MOV	BX,10  ;bx代表进制数
		DIV	BX
		PUSH	DX  ;把余数压栈
		INC	CX      ;统计有几个数进栈了
		CMP	AX,0 
		JZ	L2      ;到0,那么就不用再继续了
		JMP	L1
L2:		POP	DX      
		ADD	DL,30H  ;原文是OR,我改成了AND
		MOV	AH,2
		INT	21H
    LOOP	L2	
		RET
OUTNUM	ENDP	
    
CODES	ENDS
    		END 	START
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Meow_Sir

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值