王爽 汇编语言个人疑问汇总第九篇

第11章

实验11 编写子程序

  • 编写一个子程序,将包含任一字符,以0结尾的字符串中的小写字母转变成大写字母。

  • 描述如下:

    名称:letterc

    功能:将以-结尾的字符串中的小写字母转变成大写字母

    参数:ds:si指向字符串首地址

程序分析

  • 要把字符串中的小写字母转化为大写字母,就要把字符串中的小写字母识别出来,在ASCII码中小写字母区间是[61h,7ah],所以只要满足低于61h高于7ah的字符就是大写字母

完整代码

assume cs:code
data segment
    db "Beginner's All-purpose Symbolic Instruction Code.",0
data ends

code segment

		begin:
			mov ax,data
			mov ds,ax
			mov si,0
			call letterc  ;调用子程序
			
			mov ax,4c00h
			int 21h
		letterc:
			push cx ; 保护现场
			pushf   ; 保护现场
			mov cx,0 ; cx 设置为0
		s1:
			mov cl,ds:[si] 
			jcxz ok_ret ; 如果取到最后一个字节0 , 就跳转到ok_ret代码段
			cmp cl,61h  
			jb nextgo   ;低于61h转移
			cmp cl,7ah  
			ja nextgo   ;高于7ah转移
			and cl,0dfh  ;转化为大写,二进制是11011111 ,大写第5位是0,“与” 都为1时就是1,这里“与”第5为都会是0,转为大写
 			mov ds:[si],cl
		nextgo:
			inc si     ; 下一个字节
			jmp short s1  ; 跳转到s1代码段
		ok_ret:
			popf  ; 还原现场
			pop cx ; 还原现场
			ret     ;返回
			
			
code ends
end begin
    
assume cs:code
data segment
    db "Beginner's All-purpose Symbolic Instruction Code.",0
data ends

code segment

		begin:
			mov ax,data
			mov ds,ax
			mov si,0
			call letterc  ;调用子程序
			
			;------------------打印字符串 start----------------------
			
			mov dh,8     ; 第8行
			mov dl,3     ; 第3列
			mov cl,2     ; 颜色 2 的二进制是10,
						 ; 参考书上实验9 根据材料编程对颜色的说明可得知
						 ; 此处表示绿色
							
			mov ax,data  ; 代码段data指向ax寄存器
			mov ds,ax    ; (ds) = (ax)
			mov si,0     ; 字符串的首地址
			call show_str  ; 调用子程序
		 
       ;------------------打印字符串 end----------------------
			mov ax,4c00h
			int 21h
		letterc:
			push cx ; 保护现场
			pushf   ; 保护现场
			mov cx,0 ; cx 设置为0
		s1:
			mov cl,ds:[si] 
			jcxz ok_ret ; 如果取到最后一个字节0 , 就跳转到ok_ret代码段
			cmp cl,61h  
			jb nextgo   ;低于61h转移
			cmp cl,7ah  
			ja nextgo   ;高于7ah转移
			and cl,0dfh  ;转化为大写,二进制是11011111 ,大写第5位是0,“与” 都为1时就是1,这里“与”第5为都会是0,转为大写
 			mov ds:[si],cl
		nextgo:
			inc si     ; 下一个字节
			jmp short s1  ; 跳转到s1代码段
		ok_ret:
			popf  ; 还原现场
			pop cx ; 还原现场
			ret     ;返回
			
		;-----------------------------打印字符串 start----------------------
		show_str:	;其实这是一个子程序,里面是包含s和ok的,这样理解容易些
			push ax
			push bx
			push dx
			push cx
			push es
			push si       ; 保存程序中用到的相关寄存器,对于这个程序中其实并没有使用到从栈中取出的寄存器数据,
						  ; 个人觉得可能是一种编码习惯吧,放到栈中保护现场,以便后续的功能用到


			mov al,160  ; 每行80个字符,所以每行占160个字节(参考参考书上实验9 根据材料编程对颜色的说明可得知), 160 和 下面dh的值都小于255,做8位乘法
			mul dh      ; (dh) = 8
			mov bx,ax   ; 160 * dh 运算结果在ax中 , 再赋值给bx ,计算的行的偏移量
			mov al,2    ; 计算列的偏移量,每列占2个字节
			mul dl       ; (dl) = 2
			add bx,ax	 ;计算出行和列加起来的偏移量,放在bx里
			sub bx,2     ; 列号从0开始,最终结果要-2 才会显示在第3列
			mov ax,0B800h  ; 显示缓冲区固定地址
			mov es,ax	  ;通过段寄存器es来操控要显示的内容,es:[bx]为要输入的显示区
			mov al,cl	 ;先将cl中的颜色放在al
			mov ch,0	 ;cx高位ch为0,因为用不上
			
		s:	 
			mov cl,[si]        ; 把代码段中的数据赋值给cx寄存器低位cl
			jcxz ok            ;  利用jcxz指令特性,cx=0时就会调用ok代码段,程序调用ok代码段,最后返回。
			mov es:[bx],cl     ; 低位存字符
			mov es:[bx+1],al   ; 高位存颜色
			add bx,2           ; 往前偏移2个字节(1个字节存字符,1个字节存颜色),准备存下一个字符
			inc si             ; 下一个字符的偏移量
			jmp short s        ; 跳转到s代码段第一行指令
			
		ok:	;返回
			pop si   ; 把前面放入栈中的寄存器,依次取出来,相当于还原了
			pop es
			pop cx
			pop dx
			pop bx
			pop ax    
			
			ret 
		;-----------------------------打印字符串 end----------------------
			
code ends
end begin
  • 结果
    在这里插入图片描述

本题参考

第12章

检测点12.1

(1)

  • 用Debug查看内存,情况如下:
0000:0000 68 10 A7 00 8B 01 70 00-16 00 9D 03 8B 01 70 00
分析
  • 一个表项占两个字,也就是4个字节。高地址存放段地址,低地址存放偏移地址。
  • 对于68 10 A7 00是0号中断处理入口地址,也就是007A:1068。然后依次往下数。
答案
  • 则3号中断源对应的中断处理程序的入口地址为:0070:018B

(2)

  • 存储N号中断源对应的中断处理程序入口的偏移地址的内存单元的地址为:4*N
  • 存储N号中断源对应的中断处理程序入口的段地址的内存单元的地址为:4*N+2

posted on 2021-12-14 18:18  愤怒的苹果ext  阅读(69)  评论(0编辑  收藏  举报

导航