实验名称:汇编语言程序设计
实验日期:2017-05-13
实验环境:DOSBox 0.74
win10、win8、win7 64位系统均不支持16位。
64位windows没有ntvdm,ntvdm.exe描述(以下摘自百度百科):
比如,在32位系统环境下,你运行DOS程序(.com)或其他16位程序后,就会出现这个进程,不是病毒,但32位控制台程序(比如cmd.exe),它运行时并不会出现。64位操作系统则不包括此程序。
ntvdm.exe是Windows 16位虚拟机的一部分。该进程用于使16位的进程能够运行在32位的系统环境下。这个程序对你系统的正常运行是非常重要的。
众所皆知,微软新的桌面操作系统是向下兼容为旧系统开发的应用程序的(比如你可以在xp下玩仙剑奇侠传98柔情版),其中包括运行于DOS内核操作系统以及16位windowsPE格式可执行文件,以及为DOS开发的只包含16位指令、运行于处理器实模式的可执行程序/命令(排除那些试图直接操作硬件的,因为这逾越了NT内核操作系统给应用程序的权限,或者说它们试图运行于处理器的0环,与操作系统内核运行于同一级别,为了内核的安全性,这显然是不能被允许的)。
微软采用了WOW(Windows On Windows)技术使得在xp等NT内核操作系统上可以运行那些为旧版操作系统开发的应用程序,这样我们便可以正常的运行 Windows 98 的甚至是Windows 3.2的计算器程序等。让我们在Windows XP下打开Windows 3.2的应用程序,如记事本,你就会发现 NTVDM 这个程序幽灵般的出现了,还带上了一个子进程 WOWEXEC.exe,这就是 WOW 的一个体现了。
而针对那些为 DOS也就是 CPU运行于实模式的情况下开发的16位程序,微软则使用了DOS虚拟机(VM)的方法。NTVDM虚拟了一台运行DOS的计算机,使得16位程序能够在其中正常运行。
官网下载:www.dosbox.com
安装方法网上一搜一大把。。。
配置时的一点小技巧:运行安装目录下的DOSBox 0.74 Options.bat可以打开配置文件,我对配置文件做出了如下更改
[sdl]
windowresolution=1024x768
output=opengl
[autoexec]
#Lines in this section will be run at startup.
#You can put your MOUNT lines here.
mountc: c
setPATH=%PATH%;C:\vim\vim73;C:\MASM
C:
sdl段的两行是用于放大屏幕的,dos原始分辨率太下,大屏幕上看不舒服。alt+enter可以全屏
autoexec是模拟器打开之后自动执行的指令
我在这里挂载了安装目录下一个名为"c"的文件夹
并设置了环境变量,我采用的是vim编辑器,masm下放的是debug.exe,link.exe, masm.exe
编写下列程序并调试通过。
1. 通过键盘输入一个小写字母,找出对应的前导字母和后续字母,再按顺序显示这三个字母。
CODE SEGMENT
ASSUME CS:CODE
BEGIN:
MOV AH,07H
INT 21H
MOV DL,AL
MOV AH,02H
SUB DL,01H
INT 21H
ADD DL,01H
INT 21H
ADD DL,01H
INT 21H
MOV AH, 4CH
INT 21H
CODE ENDS
END BEGIN
2. 从键盘输入10个字符,然后以与键入相反的顺序将10个字符输出到显示屏幕上。(定义数据段保存录入字符)
DATA SEGMENT
ARRAY DB 10 DUP(?), 0DH, 0AH, '$'
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA
BEGIN: MOV AX, DATA
MOV DS, AX
MOV AH, 07H
MOV CX, 0AH
OPR:
INT 21H
MOV BX,CX;
SUB BX,01H
MOV [BX],AL
LOOP OPR
MOV AH, 09H
LEA DX, ARRAY
INT 21H
MOV AH, 4CH
INT 21H
CODE ENDS
END BEGIN
3. 编写一个程序,要求比较数组ARRAY中的三个16位补码,并根据比较结果在终端上显示如下信息:
1)如果三个数都不相等,显示0;
2)如果三个输油两个相等,显示1;
3)如果三个数都相当,显示2。
DATA SEGMENT
ARRAY DW 1224H, 1214H, 1234H
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA
BEGIN:
MOV AX, DATA
MOV DS, AX
LEA BX, ARRAY
MOV AX, [BX]
MOV DX, 0002H[BX]
CMP AX, DX
MOV DX, 0004H[BX]
JNE STEP1
CMP AX, DX
JNE TAG1
MOV DL, '2'
MOV AH, 02H
INT 21H
JMP OVER
STEP1: MOV AX, 0002H[BX]
CMP AX, DX
JE TAG1
MOV DL, '0'
MOV AH,02H
INT 21H
JMP OVER
TAG1: MOV DL, '1'
MOV AH, 02H
INT 21H
OVER:
MOV AH, 4CH
INT 21H
CODE ENDS
END BEGIN
4. 编写一个程序,要求通过键盘接收一个个位数N,然后显示N个字母‘$’。
CODE SEGMENT
ASSUME CS:CODE
BEGIN: MOV AH, 07H
INT 21H
MOV CL, AL
SUB CL, 30H
MOV CH, 00H
OUT1: MOV DL, '$'
MOV AH, 02H
INT 21H
LOOP OUT1
MOV AH, 4CH
INT 21H
CODE ENDS
END BEGIN
5. 将BX寄存器中的数用16位二进制数形式显示出来。
CODE SEGMENT
ASSUME CS:CODE
BEGIN: MOV AH, 01H
INT 21H
MOV BH, AL
INT 21H
MOV BL, AL
MOV AH, 02H
MOV DL, 0DH
INT 21H
MOV DL, 0AH
INT 21H
MOV CX, 16
MOV DH, 80H
LOOP16:
TEST BH, DH
JZ ZERO
MOV DL, '1'
INT 21H
SHL BX,1
LOOP LOOP16
JMP OVER
ZERO: MOV DL, '0'
INT 21H
SHL BX,1
LOOP LOOP16
OVER:
MOV AH,4CH
INT 21H
CODE ENDS
END BEGIN
6. 用15行*16列的表格形式显示ASCII码为10H-FFH的所有字符。
CODE SEGMENT
ASSUME CS:CODE
BEGIN: MOV AH,02H
MOV CX,16
MOV DL,10H
MOV BH,15
LOOP1: INT 21H
MOV BL,DL
MOV DL,20H
INT 21H
ADD BL,1
MOV DL,BL
LOOP LOOP1
MOV CX,16
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H
MOV DL,BL
DEC BH
JNZ LOOP1
MOV AL,0
MOV AH,4CH
INT 21H
CODE ENDS
END BEGIN