5.5 常见程序设计举例
DESCRIPTION
1. 常用进制数据输入的程序实现 ① 16 进制数输入 → 2 进制数存储 算法: D n-1 *16 n-1 +……+D0*16 0 ② 10 进制数输入 → 2 进制数存储 算法: D n-1 *10 n-1 +……+D0*10 0 ③ 2 进制数输入 → 2 进制数存储 算法: D n-1 *2 n-1 +……+D0*2 0. 5.5 常见程序设计举例. 例 1 :从键盘输入一个四位的 16 进制 数,以 2 进制 形式保存到 BX 中 INP_HXB PROC NEAR XOR BX, BX MOV CX, 4 - PowerPoint PPT PresentationTRANSCRIPT
1
1. 常用进制数据输入的程序实现 ① 16 进制数输入 → 2 进制数存储 算法: Dn-1*16n-1+……+D0*160
② 10 进制数输入 → 2 进制数存储 算法: Dn-1*10n-1+……+D0*100
③ 2 进制数输入 → 2 进制数存储 算法: Dn-1*2
n-1+……+D0*20
5.5 常见程序设计举例
2
例 1 :从键盘输入一个四位的 16 进制数,以 2 进制形式保存到 BX 中INP_HXB PROC NEAR XOR BX, BX MOV CX, 4NEXT_INP:MOV AH, 01H INT 21H CMP AL, 61H ;'a'-'z' JGE UPPER CMP AL, 41H ;'A'-'Z' JGE LOWER SUB AL, 30H ;'0'-'9' JMP ADJUST UPPER: SUB AL, 61H ADD AL, 10
3
LOWER: SUB AL, 41H ADD AL, 10ADJUST: CBW ;BX=BX*16+AX
XCHG AX, BXMOV DX, 16MUL DXXCHG AX, BXADD BX, AX
LOOP NEXT_INP RETINP_HXB ENDP
; 替换代码PUSH CXMOV CL, 4SHL BX, CLADD BX, AXPOP CX
16 进制输入,若输入为: 1234 ,则( BX ) =1234H ;10 进制输入,若输入为: 1234 ,则( BX ) =04D2H 。
4
2. 常用进制数据输出的程序实现 ① 2 进制数存储 → 16 进制数显示方法 1 :显示时将 2 进制数每 4 位分成一组,按组求对应的 ASCII 码送显示即可。方法 2 :除 16 取余。将 2 进制数除以 16 ,得到第一个商和余数,此第一个余数就是所求的 16 进制数的个位;再用第一个商除以 16 ,得到第二个商和余数,此第二个余数就是所求 16 进制数的十位;重复这一过程直至商为 0 ,此时的余数就是所求 16 进制数的最高位。所得余数依次入栈,显示时依次出栈并转换成 ASCII 码即可。方法 3 :将 2 进制数除以所求 16 进制数最高位的权值(如,4 位 16 进制数最高位权值为 4096 ),得到一个商和余数,此第一个商就是所求的 16 进制数的最高位;再用第一个余数除以次高位的权值,得到第二个商和余数,此第二个商就是所求 16 进制数的次高位;重复这一过程直至权值为 1 ,此时的商就是所求 16 进制数的个位,将所得商依次转换为ASCII 码送显示即可。
5
例 2 :将 BX 中的 16 位 2 进制数转换成 4 位 16进制数送出显示方法 1 :DISP_BXH PROC NEAR
MOV CL , 4MOV CH , 4
NEXT_DISP :ROL BX , CL ; 从高到低依次析取MOV AL , BLAND AL , 0FHADD AL , 30HCMP AL , 3AHJL OUTPADD AL , 07H ; 是 A ~ F ,要多加
7
6
OUTP : MOV DL , ALMOV AH , 02HINT 21HDEC CHCMP CH , 0JA NEXTMOV DL ,’ H’ ; 显示字母“ H”MOV AH , 2INT 21HRET
DISP_BXH ENDP
7
方法 2 :DISP_BXH PROC NEAR
MOV SI, 16XOR CX, CXMOV AX, BX
NEXT:MOV DX, 0DIV SI ; 商在 AX 中,余数在 DX 中PUSH DX ; 余数压栈INC CXCMP AX, 0 ; 商为 0 则完成转换JNZ NEXT
OUTP: POP DX ; 出栈ADD DL, 30HMOV AH,2INT 21HLOOP OUTPRET
DISP_BXH ENDP
8
方法 3 :DISP_BXH PROC NEAR MOV CX, 4096 CALL HEX_DIV MOV CX, 256 CALL HEX_DIV MOV CX, 16 CALL HEX_DIV MOV CX, 1 CALL HEX_DIV RET DISP_BXH ENDP
HEX_DIV PROC NEAR MOV AX, BX MOV DX, 0 DIV CX MOV BX, DX MOV DL, AL ADD DL, 30H MOV AH, 02H INT 21H RETHEX_DIV ENDP
16 进制显示,设( BX ) =1234H ,则显示结果为: 1234H ;10 进制显示,若( BX ) =1234H ,则显示结果为: 4460H 。
9
② 2 进制数存储 → 10 进制数显示方法 1 :除 10 取余。方法 2 :除权值取商。③ 2 进制数存储 → 2 进制数显示方法 1 :按位显示。方法 2 :除 2 取余。方法 3 :除权值取商。④ 对有符号数显示的扩展应用 CMP BX , 0 JGE ZS MOV DL ,’ -’ MOV AH , 2 INT 21HZS : CALL DISP_BXD
10
3.10 进制数算术运算的码制转换
输入 10 进制数
转换成 2 进制数
进行算术运算
结果转换成 10 进制数显示
结束
开始
输入 10 进制数
以 BCD 码形式保存
进行算术运算
BCD 码调整
结束
开始
逐个显示 BCD 码
11
例 3: 用乘法指令实现 32 位二进制数的相乘DATA SEGMENT
DAT1 DW 1234H, 2345HDAT2 DW 5678H, 6789HRESULT DW 4 DUP(?)
DATA ENDSSTACK SEGMENT PARA STACK
DW 20 DUP(0)STACK ENDSCODE SEGMENT
ASSUME CS:CODE, DS:DATA, SS:STACKSTART: MOV AX, DATA
MOV DS, AXMOV AX, DAT1+2MUL DAT2+2MOV RESULT+6, AXMOV RESULT+4, DX
12
MOV AX, DAT1MUL DAT2+2ADD RESULT+4, AXADC RESULT+2, DXADC RESULT, 0MUL DAT2ADD RESULT+4, AXADC RESULT+2, DXADC RESULT, 0
MOV AX, DAT1MUL DAT2ADD RESULT+2, AXADC RESUTL, DXMOV AH, 4CHINT 21H
CODE ENDSEND START
1234
452378
6789
DAT1
DAT2
RESULT
56
RESULT+2
RESULT+4
RESULT+6
13
例 4: 计算 N! ( N≥0 )这是一个递归调用的计算方法, N!=N*(N-1)*(N-2)…*1 N!=1, N=0 N!=N*(N-1)!, N>0
阶乘子程序说明,名称: FACT ,入口参数: AL=N ,出口参数: DX=N!
DATA SEGMENT
D1 DB 4 ;N=4
D2 DW 2 DUP(?) ; 存放运算结果DATA ENDS
STACK SEGMENT PARA STACK 'STACK'
SA DW 100 DUP(?)
STACK_TOP DB 0
STACK ENDS
14
CODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STACKMAIN PROC FARSTART:MOV AX,STACK MOV SS,AX LEA SP,STACK_TOP MOV AX,DATA MOV DS,AX ; 初始化 DS,SS,SP MOV DX,0 MOV AH,0 MOV BX,OFFSET D1 MOV AL,[BX] ;AL=N CALL FACT MOV [BX+1],DX ;D2=N! RETMAIN ENDP
15
FACT PROC ;N! 子程序 CMP AL,0
JNZ CHN
MOV DL,1 ;N=0 则 N!=1
RET
CHN: PUSH AX ;N 入栈 DEC AL ;N-1
CALL FACT ; 递归调用 FACT 子程序 POP AX ;N 出栈 MUL DL ;N 逐层返回相乘,结果在 AX 中 MOV DX,AX ; 送结果到 DX
RET
FACT ENDP
CODE ENDS
END START
16
FACT PROC CMP AL,0 JNZ CHN MOV DL,1 RETCHN: PUSH AX DEC AL CALL FACT POP AX MUL DL MOV DX,AX RETFACT ENDP
FACT PROC CMP AL,0 JNZ CHN MOV DL,1 RETCHN: PUSH AX DEC AL CALL FACT POP AX MUL DL MOV DX,AX RETFACT ENDP
FACT PROC CMP AL,0 JNZ CHN MOV DL,1 RETCHN: PUSH AX DEC AL CALL FACT POP AX MUL DL MOV DX,AX RETFACT ENDP
FACT PROC CMP AL,0 JNZ CHN MOV DL,1 RETCHN: PUSH AX DEC AL CALL FACT POP AX MUL DL MOV DX,AX RETFACT ENDP
AL=3, DL=3! AL=2, DL=2! AL=1, DL=1! AL=0, DL=0!
17
例 5 :从键盘输入两个整数 , 并求其和。 因键入为整数 , 故要进行如下转换: ASCII→BCD→ 二进制数 ASCII→BCD 码很简单 , 高 4 位清零即可得到非压缩的 BCD 码。 BCD→ 二进制数在本例中采用用以下方法: ((((0+ 千位数 )*10+ 百位数 )*10)+ 十位数 )*10+ 个位数
第一次中间结果
第二次中间结果
第三次中间结果
最终结果
18
开始
两个数分别转换成二进制数
键入两个数
相加
结束
返回 DOS
如有溢出则提示
开始
取第一个 ASCII 码
是负号吗?
数字符个数- 1 ,指针+ 1
指针定位
字符个数- 1
= 0 ?
取数字,与中间结果相加,再乘以 10
指向下一个数字字符
加个位数
是负数则求补
存结果
结束
N
Y
Y
N
转换子程序
19
程序如下:DATA SEGMENTSTR1 DB 10,?,10 DUP(?) ; 第 1 个数的输入缓冲区STR2 DB 10,?,10 DUP(?) ; 第 2 个数的输入缓冲区NUM DW ?,? ; 存转换后的二进制数SUM DW 0 ; 存和OVER DB ‘Overflow!’,13,10,’$’DATA ENDS;CODE SEGMENT
ASSUME CS:CODE,DS:DATAMAIN PROC FAR
20
START: MOV AX,DATAMOV DS,AXMOV AH,0AHLEA DX,STR1INT 21H ; 输入第一个数字串 ( 设为 26)MOV AH,0AHLEA DX,STR2INT 21H ; 输入第二个数字串 ( 设为 33)LEA BX,STR1 ; 串 1 的首地址送 BXLEA DI,NUM ; 存二进制首地址送 DI
CALL CHANGE ; 将串 1 ASCII 码→二进制 LEA BX,STR2 ; 串 2 的 首 地 址 送 BX
21
LEA DI,NUM+2 ; 指向下一个数CALL CHANGE ; 将串 2 ASCII 码→二进制MOV AX,NUM ;(AX)=[NUM]=001AH ADD AX,NUM+2 ; 两数相加 ,(AX)=003BHMOV SUM,AX ; 存和JNO NEXT ; 无溢出 , 转 NEXTLEA DX,OVERMOV AH,9INT 21H ; 显示’ Overflow!’
NEXT: MOV AH,4CHINT 21H ; 返回 DOS
MAIN ENDP
22
CHANGE PROCMOV CL,[BX+1] ; 实际字符数送 CLMOV AL,[BX+2] ; 第一个字符送 ALMOV CH,AL ; 暂存在 CHCMP AL,’-’ ; 第 一 个 字 符 是
负号吗 ?JNZ NEXT1 ; 不是 , 转 NEXT
1DEC CL ; 字符数减 1INC BX
NEXT1: ADD BX,2 ; 指向第一个数字字符MOV AX,0 ; 清零 AX, 存二进制数
LP1: DEC CLJZ NEXT2 ; 若 (CL)=0, 转
NEXT2MOV DL,[BX] ; 取字符AND DL,0FH ; 转换成 BCD 码
ADD AL,DL ; 加到中间结果上 ADC AH,0
23
MOV DX,10 MUL DX ;*10 INC BX ; 指向下一个字符 JMP SHORT LP1NEXT2: MOV DL,[BX] ; 取个位数 AND DL,0FH ; 个位 ASCII→ 未组合 BCD ADD AX,DX ; 加个位数 ,(AX)=001AH CMP CH,’-’ ; 是’ -’? JNZ NEXT3 ; 该数非负 , 转 NEXT3 NEG AX ; 若为负 , 求补NEXT3: MOV [DI],AX ; 存二进制结果 RETCHANGE ENDP;CODE ENDS END START
24
020A
32360D…
020A
33330D…
001A
21003B00
STR1
STR2
NUM
SUM
10 个
10 个
‘O’……
OVER
?
?
040A
3132
34
…
STR1
若键入 ‘ 1234’
33
0D
‘1’‘2’‘3’‘4’
…
设键入第设键入第 11 个数为个数为 26, 26, 第第 22 个数为个数为 33,33, 则在内存各变量分配则在内存各变量分配如下如下 ::
25
本例题重点掌握 :*如何从键盘输入一个字符串* ASCII→ 非压缩 BCD→ 二进制*有符号数的运算 , 对负数和溢出如何处理
思考题 : 若键入第一个数 26, 第二个数为 -4,填写各变量结果。