汇编语言关于程序的模块化编写
模块化程序设计
mul乘法指令
- 要么都是8位,要么都是16位
- 8位:一个数放在AL中,另一个数放在8位reg寄存器或内存单元中
- 16位:一个数放在AX中,另一个数放在16位reg寄存器或内存单元中
- 结果:8位乘法:放在AX中;16位乘法:低位放在AX中,高位放在DX中
8位乘8位:
assume cs:code code segment start: mov al,100 mov bl,10 mul bl code ends end start
100和10 都是8位(小于256),所以一个数放在al中,另一个数放在另一个8位reg寄存器中,结果放在ax中。 执行结果:ax=03e8h
16位乘16位:
assume cs:code code segment start: mov ax,100 mov bx,10000 mul bl code ends end start
由于bx为16位,所以另一个数一定为16位,16位对16位,ax存放一个树,16位reg寄存器存放另一个数。结果结果:ax=4240(低16位) dx=0001(高16位)
模块化程序设计
三个示例来解决模块化程序设计需要注意的三个问题
参数传递的问题
示例:使用子程序的思想,计算N的3次方
可以使用mul指令,进行三次ax与reg寄存器相乘。将结果存放在dx或ax中
; 计算N的3次方 assume cs:code data segment dw 1,2,3,4,5,6,7,8 ;存放原始数据 dd 0,0,0,0,0,0,0,0 ;存放相乘结果 data ends code segment start: mov ax,data mov ds,ax mov di,0 ;原始数据的起始地址 mov si,16 ;结果存储的起始地址 mov cx,8 s: mov bx,[di] call go ;返回到这里 mov [si],ax ;ax存放低16位 mov [si+2],dx ;dx存放高16位 add di,2 ;数据移动 add si,4 ;目标位置移动 loop s ;结束程序 mov ax,4c00h int 21h go: mov ax,bx mul bx mul bx ret ;返回主程序 code ends end start
分别计算每一个数字的3次方,将结果存储到dd的双字型内存单元中,从主程序传递ds数据到子程序,计算后返回结果送到目的地,同时注意原始数据和目标数据的偏移地址的移动
批量数据传递
示例:将一个字符串全部转换为大写
批量的将字符串长度和地址传递给子程序,进行转换后再回到主程序
提示:
- 将小写字母转换为大写字母: 与运算: and al,11011111B
- 将大写字母转换为小写字母: 或运算: or al,00100000B
;转大写 assume cs:code data segment db 'woshixiaoxiehhhh' data ends code segment start: mov ax,data mov ds,ax mov bx,0 mov si,0 ;字符串的偏移地址 mov cx,16 ;字符串长度 call go ;程序结束 mov ax,4c00h int 21h go: and byte ptr [si],11011111B ;指明接受的是byte型字节数据 inc si ;偏移地址移动定位每个字符 loop go ;循环处理每个字符 ret ;返回主程序 code ends end s
传递给子程序长度,即cx,来在子程序中对每个字母进行与运算,处理完毕后在统一回到主程序
寄存器冲突问题
示例:将多个字符串转换为大写
和上一题基本一致,但是要处理多行,用一个si或者di记录位置,这样能解决吗?
提示:没必要传给子程序cx来记录字符串的长度,直接用jcxz(如果cx为0,则执行跳转)来检测结束
;jcxz检测零实现 assume cs:code data segment db 'woshixiaoxie',0,0,0,0 db 'woshixiaoxie',0,0,0,0 db 'woshixiaoxie',0,0,0,0 db 'woshixiaoxie',0,0,0,0 db 'woshixiaoxie',0,0,0,0 data ends code segment start: mov ax,data mov ds,ax mov bx,0 mov cx,5 s1: mov si,bx ;字符串的偏移地址 push cx ;临时保存主程序CX call go ;CX出栈,保持主程序和子程序的cx不一样 pop cx ;临时保存cx add bx,16 ;换行 loop s1 ;循环 mov ax,4c00h int 21h go: mov cl,[si] mov ch,0 ;判断cx是否为零 jcxz over ;使用jcxz则无需直到字符串的长度,只要cx为零,则终止 and byte ptr [si],11011111B inc si ;偏移地址移动定位每个字符 loop go ;循环处理每个字符 over: ret ;返回主程序 code ends end start
注意:此题用jcxz over表示遇到零则结束,在子程序中将按照ds数据段的数据来判断CX,进而判断字符除按是否到达末尾,最后利用jcxz返回主程序。注意!!!!!!
在返回主程序后!!子程序的cx也会返回,进而覆盖了主程序的cx(原本外层的cx用来换行每一个字符串),因此需要利用在进入子程序之前或者进入子程序马上push cx来保存外层的cx,在结束到over或者处理结束进入主程序之后再pop cx得到原来外层的cx,进而进行下一行字符串的处理
本文来自博客园,作者:hugeYlh,转载请注明原文链接:https://www.cnblogs.com/helloylh/p/17209722.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)