5.5 常见程序设计举例

25
1 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 常常常常常常常常

Upload: giselle-whitaker

Post on 02-Jan-2016

107 views

Category:

Documents


28 download

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 Presentation

TRANSCRIPT

Page 1: 5.5  常见程序设计举例

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 常见程序设计举例

Page 2: 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

Page 3: 5.5  常见程序设计举例

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 。

Page 4: 5.5  常见程序设计举例

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 码送显示即可。

Page 5: 5.5  常见程序设计举例

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

Page 6: 5.5  常见程序设计举例

6

OUTP : MOV DL , ALMOV AH , 02HINT 21HDEC CHCMP CH , 0JA NEXTMOV DL ,’ H’ ; 显示字母“ H”MOV AH , 2INT 21HRET

DISP_BXH ENDP

Page 7: 5.5  常见程序设计举例

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

Page 8: 5.5  常见程序设计举例

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 。

Page 9: 5.5  常见程序设计举例

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

Page 10: 5.5  常见程序设计举例

10

3.10 进制数算术运算的码制转换

输入 10 进制数

转换成 2 进制数

进行算术运算

结果转换成 10 进制数显示

结束

开始

输入 10 进制数

以 BCD 码形式保存

进行算术运算

BCD 码调整

结束

开始

逐个显示 BCD 码

Page 11: 5.5  常见程序设计举例

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

Page 12: 5.5  常见程序设计举例

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

Page 13: 5.5  常见程序设计举例

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

Page 14: 5.5  常见程序设计举例

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

Page 15: 5.5  常见程序设计举例

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

Page 16: 5.5  常见程序设计举例

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!

Page 17: 5.5  常见程序设计举例

17

例 5 :从键盘输入两个整数 , 并求其和。 因键入为整数 , 故要进行如下转换: ASCII→BCD→ 二进制数 ASCII→BCD 码很简单 , 高 4 位清零即可得到非压缩的 BCD 码。 BCD→ 二进制数在本例中采用用以下方法: ((((0+ 千位数 )*10+ 百位数 )*10)+ 十位数 )*10+ 个位数

第一次中间结果

第二次中间结果

第三次中间结果

最终结果

Page 18: 5.5  常见程序设计举例

18

开始

两个数分别转换成二进制数

键入两个数

相加

结束

返回 DOS

如有溢出则提示

开始

取第一个 ASCII 码

是负号吗?

数字符个数- 1 ,指针+ 1

指针定位

字符个数- 1

= 0 ?

取数字,与中间结果相加,再乘以 10

指向下一个数字字符

加个位数

是负数则求补

存结果

结束

N

Y

Y

N

转换子程序

Page 19: 5.5  常见程序设计举例

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

Page 20: 5.5  常见程序设计举例

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

Page 21: 5.5  常见程序设计举例

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

Page 22: 5.5  常见程序设计举例

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

Page 23: 5.5  常见程序设计举例

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

Page 24: 5.5  常见程序设计举例

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, 则在内存各变量分配则在内存各变量分配如下如下 ::

Page 25: 5.5  常见程序设计举例

25

本例题重点掌握 :*如何从键盘输入一个字符串* ASCII→ 非压缩 BCD→ 二进制*有符号数的运算 , 对负数和溢出如何处理

思考题 : 若键入第一个数 26, 第二个数为 -4,填写各变量结果。