汇编语言程序设计(2)
无 88 981239 石光实验目的掌握子程序的编程方法掌握宏指令与宏指令调用的编程方法掌握C语言与汇编语言的混合编程方法
实验内容编写一个程序,将用户从键盘输入的十进制数(不超过65535)转换成十六进制数并显示。
***************** 程序清单 ********************
D SEGMENT
OUTPUT DB'ENTER A DECIMAL NUMBER(<65535):',0DH,0AH,'$'
NUM DB 8
DB ?
DB 8 DUP(?)
EEQQ DW 0
ASCII DB '0123456789ABCDEF'
EO DB 0DH,0AH,'INPUT ERROR!',0DH,0AH,'$'
RE1 DB 0
RE2 DB 0
RE3 DB 0
RE4 DB 0
RESULT1 DB 0DH,0AH,'THE CONVERTED HEHADECIMAL NUMBER IS:$'
RESULT2 DB 'H'
D ENDS ;定义数据段
CEG SEGMENT
ASSUME CS:CEG,DS:D ;定义代码段
START,
MOV AX,D
MOV DS,AX ;给数据段赋初值
LEA DX,OUTPUT
MOV AH,9
INT 21H
LEA DX,NUM ;显示输入提示字符串
MOV AH,0AH
INT 21H ;读取字符串
CALL CHECK ;调用第一个子程序,检查字符串是否正确
CALL DTOH ;调用第二个子程序,将十进制数ASCII串转换成十六进制数
CALL HTOA ;调用第三个子程序,将十六进制数转换成ASCII串
LEA DX,RESULT1
MOV AH,9
INT 21H ;显示输出提示字符串
LEA SI,RE4
MOV DL,[SI]
MOV AH,2
INT 21H
LEA SI,RE3
MOV DL,[SI]
MOV AH,2
INT 21H
LEA SI,RE2
MOV DL,[SI]
MOV AH,2
INT 21H
LEA SI,RE1
MOV DL,[SI]
MOV AH,2
INT 21H
LEA SI,RESULT2 ;分别输出四位
MOV DL,[SI]
MOV AH,2
INT 21H
LAST, MOV AH,4CH ;返回DOS状态
INT 21H
CHECK PROC ;定义子程序
LEA DI,NUM ;DI保存数据地址
INC DI ;DI指向下一位
MOV CL,[DI] ;CL保存数据位数
AND CX,000FH
INC DI ;DI指向下一位
AG: MOV AL,[DI]
CMP AL,'9'
JA EERR
CMP AL,'0'
JB EERR
INC DI
LOOP AG
JMP RE ;若输入的字符串中含有非0~9的字符,显示出错信息
EERR, LEA DX,EO
MOV AH,9
INT 21H
JMP LAST
RE: RET
CHECK ENDP
DTOH PROC ;定义子程序
LEA DI,NUM ;DI保存数据地址
INC DI ;DI指向下一位
MOV CL,[DI] ;CL保存数据位数
AND CX,000FH
MOV AX,0
MOV BX,0 ;清空AX,BX
MOV SI,10 ;SI赋十
AD: MUL SI
INC DI
MOV BL,[DI]
AND BL,0FH
ADC AX,BX
LOOP AD
MOV EEQQ,AX ;循环累加
RET
DTOH ENDP
HTOA PROC ;定义子程序
MOV AX,EEQQ ;读取数据
AND AL,0FH
LEA BX,ASCII
XLAT ASCII
MOV RE1,AL ;将十六进制数转换成ASCII码并保存
MOV DL,AL
MOV AX,EEQQ
MOV AH,0
AND AL,0F0H
MOV CL,4
SHR AL,CL
LEA BX,ASCII
XLAT ASCII
MOV RE2,AL ;将十六进制数转换成ASCII码并保存
MOV DL,AL
MOV AX,EEQQ
AND AH,0FH
MOV AL,AH
LEA BX,ASCII
XLAT ASCII
MOV RE3,AL ;将十六进制数转换成ASCII码并保存
MOV DL,AL
MOV AX,EEQQ
MOV AH,0
AND AL,0F0H
MOV CL,4
SHR AL,CL
MOV AL,AH
LEA BX,ASCII
XLAT ASCII
MOV RE4,AL ;将十六进制数转换成ASCII码并保存
RET
HTOA ENDP

CEG ENDS
END START
2,编写一个程序,对键盘输入的两个字符串进行比较,输入的字符串长度不超过80。
***************** 程序清单 *************************
D SEGMENT ;定义代码段
STRING1 DB 'Enter the first string(NUMBER<80):',0DH,0AH,'$'
STRING2 DB 0DH,0AH,'Enter the second string (NUMBER<80):',0DH,0AH,'$'
RESULT1 DB 0DH,0AH,'The two string are identical',0DH,0AH,'$'
RESULT2 DB 0DH,0AH,'The two string are not identical',0DH,0AH,'$'
IN1 DB 100 ;开辟第一个字符串缓冲区
DB?
DB 100 DUP (?)
IN2 DB 100 ;开辟第二个字符串缓冲区
DB?
DB 100 DUP (?)
D ENDS
OUTPUT MACRO DAT ;定义显示字符串的宏
MOV DX,OFFSET DAT
MOV AH,9
INT 21H
ENDM
CSEG SEGMENT ;初始化数据段
ASSUME CS:CSEG,DS:D
START:MOV AX,D
MOV DS,AX
OUTPUT STRING1 ;显示输入提示字符串
LEA DX,IN1
MOV AH,0AH
INT 21H ;存第一个字符串
OUTPUT STRING2
LEA DX,IN2
MOV AH,0AH
INT 21H ;存第二个字符串
LEA SI,IN1
LEA DI,IN2
INC SI
INC DI
MOV AH,[SI]
MOV AL,[DI]
CMP AH,AL ;比较两串长度
JNE NOTSAME
MOV CL,AL ;两串同长时,记录实际串长
INC SI
INC DI
AG,MOV AL,[SI]
MOV AH,[DI]
CMP AH,AL
JNE NOTSAME
INC SI
INC DI
LOOP AG ;从前向后逐位比较,不同则跳出循环
OUTPUT RESULT1 ;正常结束循环,两串相同
JMP EXTOUT
NOTSAME,OUTPUT RESULT2
EXTOUT,MOV AH,4CH
INT 21H
CSEG ENDS
END START
3,编写两个汇编语言子程序,分别返回系统的当前日期和时间;编写一个C语言程序,调用汇编语言子程序,显示系统的当前日期和时间
***************************程序清单 *****************************
.model small
.code
public _time
_time proc
mov ah,2ch
int 21h
mov ax,cx
ret ;返回系统时间
_time endp ;dh秒,dl百分秒。ah小时,al分
end

.model small
.code
public _date
_date proc
mov ah,2ah
int 21h
mov ax,cx
ret ;返回系统日期
_date endp
end ;dh月,dl日。ax年
C语言源程序
#include "stdio.h"
extern long date();
extern long time();/*定义为全局函数变量,并且是长整型的,正好是能装下dx,ax中的32位机器数*/
main ()
{long date1, date2;
long time1, time2;
int year, month, day;
int hour, min, sec, psec ; /*定义变量*/
date1=date();
date2=date1; /* 得到返回的32位机器数 */
time1=time();
time2=time1; /* 得到返回的32位机器数 */
date2=(date2>>24)&0x000000ff;
month=(int)date2; /* 月份是最高8位,须将变量右移24位,并强制转化为字符型 */
date2=date1;
date2=(date2>>16)&0x000000ff;
day=(int)date2; /* 日期是次高8位,须将变量右移16位,并强制转化为字符型 */
date2=date1;
date2=date2&0x0000ffff;
year=(int)date2; /* 年份是后16位 */
time2=(time2>>24)&0x000000ff;
sec=(int)time2; /* 秒是最高8位,须将变量右移24位,并强制转化为字符型 */
time2=time1;
time2=(time2>>16)&0x000000ff;
psec=(int)time2; /* 百分秒是次高8位,须将变量右移24位,并强制转化为字符型 */
time2=time1;
time2=(time2>>8)&0x000000ff;
hour=(int)time2; /* 小时是ax高8位,须将变量右移8位,并强制转化为字符型 */
time2=time1;
time2=time2&0x000000ff;
min=(int)time2; /* 分是ax低8位,强制转化为字符型即可 */
printf("\nCurrent date is %d-%d-%d,",month,day,year);
printf(" Current time is %d:%d:%d.%d",hour,min,sec,psec);
}
说明:
以上程序均编译通过,有些程序为了清晰可读而使用了较多变量使效率减低了。