|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
- assume cs:code,ds:data
- data segment
- db 10 dup(0)
- data ends
- code segment
- start:
- mov ax,12666 ;需要处理的字符
-
- mov bx,data ;ds:si指向字符串的首地址
- mov ds,bx
- mov si,0
-
- call dtoc ;dtoc子程序实现将word型整数转化为字符串并存储
-
- mov dh,8 ;初始化打印(显示)的位置
- mov dl,3
- mov cl,0cah
-
- call show_str ;开始打印字符串
-
- mov ax,4c00h
- int 21h
-
- dtoc: ;数值显示的子程序定义
- push dx
- push cx
- push ax
- push si
- push bx
-
- mov bx,0 ;bx在子程序中用来存放位数,用栈来临时存放修改后的字符
-
- s1: mov cx,10d ;d表示10进制(除数)
- mov dx,0
-
- div cx ;除以10
- mov cx,ax ;得到的商赋值给cx
-
- jcxz s2 ;当商为0的时候跳到s2(cx用来判断)已经到了个位(余数是个位)
-
- add dx,30h ;将余数加上20h得到相应的ASCLL码
- push dx ;将数据存放入栈
-
- inc bx ;bx记录栈存放了多少位数
-
- jmp short s1
-
- s2: add dx,30h ;当商为0的时候,余数为个位
- push dx
- inc bx ;再进行一次栈操作(补充当“商为0而余数不为0时的情况”)
-
- mov cx,bx ;总共有bx位进栈了,所以循环次数为bx
- mov si,0
-
- s3: pop ax ;s3实现将栈中的数据一次出栈放到指定内存中
- mov [si],al
- inc si
-
- loop s3
-
- okay: pop bx
- pop si
- pop ax
- pop cx
- pop dx
-
- ret ;数值显示的子程序定义结束
-
- show_str:
- push cx
- push si
-
- mov al,0a0h ;每行有多少个字节(160)
-
- dec dh ;行号从下标0开始,所以减1
- mul dh ;相当于从第(n-1)* 0a0h个byte单元开始
- ;乘法之后默认放在ax中
- mov bx,ax ;定位好的位置偏移地址存放在bx里(行)
-
- mov al,2 ;每个字符占两个字节
- mul dl ;定位列,结果ax存放的是定位好的列的位置
- sub ax,2 ;列号在显存中下标从0开始,偶字节存放字符,所以减2
-
- add bx,ax ;此时bx中存放的是行与列号的偏移地址(行的偏移地址加上列的偏移地址)
-
- mov ax,0b800h ;显存开始的地址
- mov es,ax ;es中存放的是显存的第0页(共0~7页)的起始的段地址
-
- mov di,0 ;di指向显存的偏移地址,确定指向下一个要处理的字符的位置
-
- mov al,cl ;cl是存放颜色的参数,这时候al存放颜色了
- ;因为下边cl要用来陇南市存放要处理的字符(判断跳转指令通过cx确定)
- mov ch,0 ;下边cx存放的是每次准备处理的字符
-
- s: mov cl,ds:[si] ;ds:[si]指向“Welcome 头 masm!”,0
-
- jcxz ok ;当cl的值为0的时候,cx==0,则发生跳转,到0k处结束处理
-
- mov es:[bx+di],cl ;偶地址存放字符
- mov es:[bx+di+1],al ;奇地址存放字符的颜色属性
-
- inc si ;指向下一个字符(源字符串)
-
- add di,2 ;指向下一个字符(目的字符串)
- jmp short s ;无条件跳转,jcxz是离开的关键跳
-
- ok: pop si
- pop cx
-
- ret ;显示字符串的子程序【定义结束】
-
- code ends
- end start
-
复制代码 感觉s2这个标记后面没必要,s1和s2进行的都是同一个操作,,为什么要分两个?应该可以合成一个循环中,不知道我的想法对不对??
|
|