标签:href 初始 bilibili 准备 颜色 www start 取颜色 asm
assume cs:code,ds:data,ss:stack
data segment
db 'welcome to masm!' ;定义要显示的字符串(共16字节)
db 02h,24h,71h ;分别定义三行的属性,即定义三种颜色属性
data ends
stack segment
dw 8 dup (0) ;定义一个栈段,用于暂存数据,存储ax、bx等寄存器值
;因为这些寄存器是16位的,所以定义的栈也是字型的
stack ends
code segment
start: mov ax,data
mov ds,ax ;将data和ds挂钩
mov ax,stack
mov ss,ax ;将stack和ss挂钩
mov sp,10h ;因为栈大小dw 8就是16个字节,所以栈的初始地址
;指向栈顶,也是16个字节,即十六进制表示为10h
xor bx,bx ;bx清零,用来索引颜色。相当于mov bx,0
;即bx用来索引颜色
mov ax,0b872h ;屏幕总共显示25行,中间3行是12、13、14
;算出屏幕第12行中间的显存的段起始位置放入ax中
;前面有11行,每行160个字节:11*160=1760
;即第12行的开始地址为1760,现要求显示在中间
;打印16个字符的字符串。每行有80个字符,也就是
;前面32个字符,后面32个字符,中间正好16个字符。
;32个字符,每个字符占2个字节(第一个字节表示字
;符,第二个字节表示属性),32*2=64。
;1760+64=1824(十六进制:720h)
;因为显存的起始地址为 b8000h,b8000h+720h=b8720h
;我们把它当成一个段地址就是b872h,该地址其实就是字符
;串起始字符w的地址。
mov cx,3 ;s3循环控制行数,外循环为3次,因为要显示3行字符串
s3: push cx ;三个进栈操作为外循环s3保存相关寄存器的值
push ax ;以防止它们的值在内循环中被破坏,因为内层
push bx ;循环用到了相关寄存器,值会被覆盖
mov es,ax ;此时es为屏幕第12行中间的显存的段起始位置
mov si,0 ;si用来索引字符串的每个字符
mov di,0 ;di用来确定每个字符的偏移地址
mov cx,10h
;s1循环实现每行16个字符的写入,内循环为16次,因为字符串中含16个字节
s1: mov al,ds:[si] ;比如ds:[0]就是数据段的w字符
mov es:[di],al ;相应es:[di]=b872:0处显示w的效果
inc si
add di,2 ;di是要加2的,因为2个字节确定一个字符的显示效果
loop s1 ;循环16次,实现偶地址中存放字符
mov di,1 ;di的值设为1,从而为在显存奇地址中存放字符的颜色属性作准备
pop bx
mov al,ds:10h[bx] ;取颜色属性存放在al中。ds:10h[bx]指向数据段中的02h
inc bx ;bx加1,为取下一行颜色属性作准备
mov cx,10h ;第二个内循环也为16次
s2: mov cs:[di],al
add di,2 ;di初值1,每次循环加2。正好实现在每个字符的第二个字节单元填充颜色属性
loop s2 ;此循环实现奇地址中存放字符的颜色属性
;以下4句为下一趟外循环作准备
pop ax
add ax,0ah ;将显存的段起始地址设为当前行的下一行
;[在段地址中加0ah,相当于在偏移地址中加了0a0h(=160d)]
pop cx
loop s3
mov ax,4c00h
int 21h
code ends
end start
附:小甲鱼视频讲解
标签:href 初始 bilibili 准备 颜色 www start 取颜色 asm
原文地址:https://www.cnblogs.com/doctorx/p/9678226.html