文章目录
前言
王爽老师《汇编语言》(第四版)第七章 实验6 (程序7.9)分析及代码
一、题目
编程,将data段中的每个单词的前4个字母改为大写。
assume cs:code,ds:data,ss:stack
data segment
db '1. display '
db '2. brows '
db '3. replace '
db '4. modify '
data ends
stack segment
dw 0,0,0,0,0,0,0,0
stack ends
code segment
start:
; ? 代码写在这里
code ends
end start
二、分析
1.从数据结构角度理解题目
为了方便,每一个单词后边都加了空格,这样每一个单词其实都占了16个字节。要修改的单词一共有四个,每个单词字符串中要修改的是第3-6(从0开始计数)个字符。这就可以理解为高级编程语言中的二维数组。很容易想到,可以通过二维数组遍历的方式来完成题目。
2.外层循环计数器的问题 & 栈的使用
但是这里有一个问题,在高级编程语言中,内外层循环可以定义不同的变量作为计数器,但是汇编语言中默认使用cx寄存器作为循环次数的计数器。
可以想到的办法是,使用另外的寄存器来暂存外层循环要使用的cx的数据。但是寄存器数量毕竟是有限的,更好的方法是,将以后还要使用的数据存储到内存中,需要用的时候再从内存中取出来。
一般来说,需要暂存数据的时候,就应该使用栈,利用push和pop指令存取数据。
3.字母的大小写转换
计算机中存储的是二进制,首先想到的方法大概是通过条件判断语句,先判断字符是大写还是小写字母,再决定是否进行转换。但是现在还没学习到判断语句,就要另想办法。
通过观察,ASCII码中每一个字母都占一个字节,也就是两个16进制位(或者是8个二进制位)。由于小写字母对应的十六进制一定是6XH或者7XH,那么它对应的二进制的高四位就应该是0110B或者0111B。而大写字母对应的十六进制一定是4XH或者5XH,那么它对应的二进制的高四位就应该是0100B或者0101B。
观察可得,如果是小写字母,那么对应的二进制的高四位一定是XX1X,而大写字母对应的二进制的高四位一定是XX0X。于是就可以利用and指令或者or指令,来完成大小写的转换。这真是很巧妙啊!
三、代码
assume cs:code,ds:data,ss:stack
data segment
db '1. display '
db '2. brows '
db '3. replace '
db '4. modify '
data ends
stack segment
dw 0,0,0,0,0,0,0,0
stack ends
code segment
start:
mov ax,data ;设置ds
mov ds,ax
mov ax,stack ;设置栈顶
mov ss,ax
mov sp,10H
mov bx,0 ;bx作为行号索引
mov cx,4 ;设置外层循环次数 初始值
s0: ;外层循环:每一遍操作一行
push cx ;将外层循环次数压入栈
mov si,3 ;列号索引
mov cx,4 ;设置内循环次数
s: ;内循环:每一遍操作一列
mov al,[bx+si] ;将内存中的值复制到al寄存器中
and al,11011111B ;把这个值变为大写字母
mov [bx+si],al ;完成后复制回内存
inc si ;列号+1
loop s
add bx,10H ;行号+1,一行占10H字节
pop cx ;将外循环次数pop出来
loop s0 ;loop执行时自动将外层循环的cx-1
mov ax,4c00h
int 21h
code ends
end start
总结
本文给出了《汇编语言》(第四版)实验6的分析与代码,并简单总结了涉及的知识点。