|
发表于 2014-4-10 14:44:51
|
显示全部楼层
本帖最后由 苏门答腊鸭 于 2014-4-10 14:46 编辑
看看这个两个循环的版本能看懂不,我已经把注释写的很详细了
- assume cs:code,ds:data,ss:stack
- data segment
- db 'welcome to masm!' ;数据段定义目标字符串
- db 02h,24h,71h ;定义颜色代码
- data ends
- stack segment
- dw 8 dup(0) ;定义一个空堆栈,用来存放不希望被内部循环修改的一些变量
- stack ends
- code segment
- start:
- mov ax,data ;data挂钩数据段
- mov ds,ax
- mov ax,stack
- mov ss,ax ;stack挂钩栈段
- mov sp,10h ;初始化栈顶指针地址
- mov ax,0b872h ;定义字符串首字符地址,这里是为了美观,定义到了屏幕居中位置
-
- mov cx,3 ;定义外部大循环计数器3次
- mov di,10h ;由于目标字符串长度16位(0--15),所以后边颜色代码从第16位开始 10H
-
- s0: mov es,ax ;外层循环:将要修改的显存区域与es挂钩
- mov bx,0 ;将要用到的‘变量’寄存器预先清零
- mov si,0
-
- push ax ;将预显示字符串首字符地址压栈保存,以免在内层循环中ax的值被修改
- push cx ;将外层循环次数压栈保存
-
- mov cx,16 ;由于目标字符串长度16位,所以设置内部循环次数为16次
-
- s1: mov al,ds:[bx] ;内部循环:将首字符赋予al,由于1个字符占一个字节,所以这里用al
- mov es:[si],al ;将al的值赋予es:0位置,也就是0b872:0位置,显示第一个字符
- mov al,ds:[di] ;将颜色代码值赋予al
- mov es:[si+1],al ;基地址存放颜色代码,所以将si+1,将al的值赋予es:01位置,也就是0b872:01处,以显示文字颜色
- add si,2 ;由于偶地址放字符,基地址放颜色代码,所以这里将si+2,以便指向下一个字符地址
- inc bx ;bx索引数据段中字符串的字符,所以每次循环自增1
- loop s1 ;循环s1,以显示第一行整个字符串中的所有字符
- inc di ;内循环结束后第一行字符串显示完毕进入外部循环,将索引颜色代码字符地址的di自增1以设置第二行字符串颜色
- pop cx ;将与现存的外循环次数出栈
- pop ax ;将预先保存的第一行首字符地址出栈
- add ax,0ah ;将第一行首字符地址+160以指向第二行首字符地址
-
- loop s0 ;大循环3次,显示3行字符串
-
- mov ax,4c00h ;大循环完毕后程序结束
- int 21h
- code ends
- end start
复制代码
|
|