微机原理实验一、编写汇编程序,从键盘接收一个小写字母,然后找出它的前导字符和后续字符,再按顺序显示这三个字符
实验目标:
8086 编写汇编程序,从键盘接收一个小写字母,然后找出它的前导字符和后续字符,再按顺序显示这三个字符
比如输入的是b,则输出的abc
一、 汇编语言中定义变量
在汇编语言中,定义变量的语法规则取决于所使用的汇编器和目标平台。一般情况下,汇编语言中定义变量的语法如下:
变量名 类型 初始值
- 变量名:变量的名称,必须符合汇编语言的标识符规则,通常使用字母开头,可以包含字母、数字和下划线。
- 类型:变量的数据类型,可以是字节、字(16位)、双字(32位)等。在汇编语言中,常见的数据类型包括
db(字节)、dw(字)、dd(双字)等。 - 初始值:可选项,表示变量的初始值。
?表示未初始化的变量,即初始值未知。
在汇编语言中,变量的定义通常出现在数据段(DATA SEGMENT)或全局数据段(.data)中。示例代码可能如下所示:
DATA SEGMENT
input_char db ?
DATA ENDS
或者在全局数据段中:
.data
input_char db ?
这样就定义了一个名为 input_char 的字节型变量,初始值未知。在程序中可以通过该变量名来访问和操作这个变量。
1.1 定义行字符序列(俗称回车+换行)
在汇编语言中,newline db 0DH, 0AH, '$' 定义了一个包含换行字符序列的字节型数组。
newline是数组的标签或名称。db表示定义字节型数据。0DH表示回车字符的ASCII码值。0AH表示换行字符的ASCII码值。'$'表示字符串的结束标志,ASCII码值为0。
因此,这行代码定义了一个包含回车和换行字符的字节型数组,用于表示换行字符序列。
1.2 定义栈
在汇编语言中,DW 20 DUP(0) 是定义一个字(16位)型数组,数组长度为20,每个元素初始值为0。
DW表示数据类型,表示字(16位)。20表示数组的长度,即数组中元素的个数。DUP(0)表示复制,将后面括号中的值复制指定次数。这里是将0复制20次,即初始化数组的所有元素为0。
因此,这行代码定义了一个包含20个字节的数组,每个字节的初始值都是0。
1.3 ASSUME CS:CODE, DS:DATA, SS:STACK
在汇编语言中,ASSUME CS:CODE, DS:DATA, SS:STACK 用于告诉汇编器代码段(CS)、数据段(DS)和堆栈段(SS)之间的关系。
CS是代码段寄存器,指示当前正在执行的指令所在的段。DS是数据段寄存器,指示数据存储的段。SS是堆栈段寄存器,指示当前堆栈操作的段。
通过 ASSUME 指令,汇编器知道在代码段中,使用标签时要从代码段中查找,而在数据段中,使用标签时要从数据段中查找。同样,堆栈操作也会在堆栈段中进行。
二、 INT 21H
INT 21H这条指令是调用 21H 中断,这是 DOS 提供的一个中断服务。当 AH 寄存器中的值指示了所需的功能时(例如,打印字符串、读取键盘输入等),执行此中断会调用相应的 DOS 功能。
| 中断 | 功能 | 入口参数 | 出口参数 |
|---|---|---|---|
| INT20 | 程序正常退出 | CS=PSP段地址 | - |
| INT21 | 系统功能调用 | AH=功能号 | - |
| INT22 | 程序结束处理 | - | - |
| INT23 | Ctrl-Break处理 | AL=0(忽略) | - |
| INT24 | 严重错误处理 | AL=驱动器号 AL=1(重试) AL=2(通过INT 23H终止) | Cy=1出错 |
| INT25 | 绝对磁盘读 | CX=读入扇区数 DX=起始逻辑扇区数 DS:BX=缓冲区地址 AL=驱动器号 | Cy=0正确 |
| INT26 | 绝对磁盘写 | CX=写盘扇区数 DX=起始逻辑扇区数 DS:BX=缓冲区地址 | - |
| INT27 | 驻留退出 | CS=PSP段地址 DX=程序末地址+1 | - |
功能号在AH中,并设好其余的入口参数,向DOS发出INT21H命令,最后获得出口参数
| 调用号(AH) | 功能 | 入口参数 | 出口参数 |
|---|---|---|---|
| 00H | 程序终止 | CS=PSP段地址 | - |
| 01H | 键盘输入字符 | - | AL=输入的字符 |
| 02H | 显示输出 | DL=显示的字符 | - |
| 03H | 串行设备输入 | - | AL=输入的字符 |
| 04H | 串行设备输出 | DL=输出的字符 | - |
| 05H | 打印输出 | DL=输出的字符 | - |
| 06H | 直接控制台I/O | DL=0FFH(输入请求) DL=字符(输出请求) | AL=输入的字符 |
| 07H | 直接控制台I/O (不显示输入) | - | AL=输入的字符 |
| 08H | 键盘输入字符(无回显) | - | AL=输入的字符 |
| 09H | 显示字符串 | DS:DX=缓冲区首址 | - |
| 0AH | 输入字符串 | DS:DX=缓冲区首址 | - |
| 0BH | 检查标准输入状态 | - | AL=00无按键 AL=0FFH有按键 |
| 0CH | 清除输入缓冲区并执行指定的标准输入功能 | AL=功能号(01/06/07/08/0AH) DS:DX=缓冲区(0AH功能) | AL=输入的数据(功能01/06/07/08) |
| 0DH | 初始化磁盘状态 | - | - |
| 0EH | 选择缺省的驱动器 | DL=驱动器号(0=A,1=B…) | AL=逻辑驱动器数 |
| 0FH | 打开文件 | DS:DX=未打开的FCB首址 | AL=00成功,0FFH失败 |
| 10H | 关闭文件 | DS:DX=打开的FCB首址 | AL=00成功,0FFH失败 |
| 11H | 查找第一匹配目录 | DS:DX=未打开的FCB首址 | AL=00成功,0FFH失败 |
| 12H | 查找下一匹配目录 | DS:DX=未打开的FCB首址 | AL=00成功,0FFH失败 |
| 13H | 删除文件 | DS:DX=未打开的FCB首址 | AL=00成功,0FFH失败 |
| 14H | 顺序读 | DS:DX=打开的FCB首址 | AL=00成功,01文件结束 02缓冲区太小 03缓冲区不满 |
| 15H | 顺序写 | DS:DX=打开的FCB首址 | AL=00成功,01盘满 02缓冲区太小 |
| 16H | 创建文件 | DS:DX=未打开的FCB首址 | AL=00成功 0FFH目录区满 |
| 17H | 文件换名 | DS:DX=被修改的FCB首址 | AL=00成功,0FFH未找到目录项或文件重名 |
| … | … | … | … |
三、 实现汇编程序
完整的代码:
;#########################################################################
; @Description: 编写汇编程序,从键盘接收一个小写字母,
; 然后找出它的前导字符和后续字符,再按顺序显示这三个字符
;* @Version: 1.0
;* @Autor: Huining Li777
;* @运行:
; Please input a char: s ----->The characters:rst
; Please input a char: q ----->The characters:pqr
;* @结束:按下回车结束
;#########################################################################
DATA SEGMENT
input_char db ? ; 输入字符变量
output_buffer db 3 DUP(?) ; 输出字符缓冲区,用于存储前导字符、输入字符和后续字符
prompt_input db 'Please input a char: $' ; 输入提示文字
prompt_output db '----->The characters: $' ; 输出提示文字
newline db 0DH, 0AH, '$' ; 换行字符序列
DATA ENDS
STACK SEGMENT STACK
DW 20 DUP(0) ; 定义一个长度为20的堆栈空间
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA, SS:STACK ; 告诉汇编器代码段、数据段和堆栈段的关系
START:
MOV AX, DATA ; 将数据段的段地址加载到 AX 寄存器中
MOV DS, AX ; 将 AX 寄存器中的数据段地址设置到 DS 寄存器,以便程序能够访问数据段中的数据
; 输出输入提示文字
MOV AH, 09H ; DOS功能号,表示"打印字符串"
LEA DX, prompt_input ; 输出输入提示文字
INT 21H ; 输出到控制台
read_loop:
MOV AH, 01H ; DOS功能号,表示"等待键盘输入"
INT 21H ; 调用21h中断
MOV input_char, AL ; 将输入的字符存储到 input_char 变量中
CMP AL, 0DH ; 检查是否输入了回车键
JE exit_program ; 如果输入了回车键,退出程序
; 计算前导字符
MOV BL, input_char ; 将输入字符存储到 BL 寄存器
DEC BL ; 前导字符为输入字符的前一个字符
MOV output_buffer, BL ; 将前导字符存储到输出字符缓冲区
; 计算后续字符
MOV BL, input_char ; 将输入字符存储到 BL 寄存器
INC BL ; 后续字符为输入字符的后一个字符
MOV output_buffer + 2, BL ; 将后续字符存储到输出字符缓冲区
; 输出输出提示文字
MOV AH, 09H ; DOS功能号,表示"打印字符串"
LEA DX, prompt_output ; 输出输出提示文字
INT 21H ; 输出到控制台
; 输出前导字符
MOV AH, 02H ; DOS功能号,表示"输出字符"
MOV DL, output_buffer ; 要输出的前导字符
INT 21H ; 输出字符到控制台
; 输出输入字符
MOV AH, 02H ; DOS功能号,表示"输出字符"
MOV DL, input_char ; 要输出的输入字符
INT 21H ; 输出字符到控制台
; 输出后续字符
MOV AH, 02H ; DOS功能号,表示"输出字符"
MOV DL, output_buffer + 2 ; 要输出的后续字符
INT 21H ; 输出字符到控制台
; 输出换行
MOV AH, 09H ; DOS功能号,表示"打印字符串"
LEA DX, newline ; 输出换行字符序列
INT 21H ; 输出换行到控制台
; 输出输入提示文字
MOV AH, 09H ; DOS功能号,表示"打印字符串"
LEA DX, prompt_input ; 输出输入提示文字
INT 21H ; 输出到控制台
JMP read_loop ; 继续循环读取字符
exit_program:
MOV AH, 4CH ; DOS功能号,表示"程序终止"
INT 21H ; 终止程序的执行
CODE ENDS
END START
本文详细介绍了如何在8086汇编环境下编写程序,从键盘接收小写字母,找出其前导字符和后续字符,并按照顺序显示。涉及变量定义、INT21H中断以及DOS功能的运用。
560

被折叠的 条评论
为什么被折叠?



