x86 masm 通用的代码记录
编写环境:vscode+DOSBox 0.7.4+masm
vscode插件:VSCode DOSBox
1. 在屏幕显示字符串
应用举例:在屏幕的8行3列,用绿色显示data段中的字符串
;名称:showstr
;功能:在指定的位置,用指定的颜色,显示一个用0结束的字符串。
;参数:(dh)=行号(取值范围0~24),(dl)=列号(取值范围 0~79),(cl)-颜色,ds:si指向字符串的首地址
;返回:无
showstr:
push ax
push cx
push dx
push es
push si
push di
mov ax,0B800H ;32kb 的显存
mov es,ax
;计算位置 25行 80列
; dh*160+dl*2
dec dh
mov al,160
mul dh
add dl,dl
mov dh,0
add ax,dx
mov di,ax
;ax: ah al ; al 存字符,ah存颜色
mov ah,cl ;ah存颜色
mov si,0
set_char:
mov cl,ds:[si]
mov ch,0
jcxz showstr_done
mov al,cl ;al 存字符
mov es:[di],ax
inc si
add di,2
jmp set_char
showstr_done:
pop di
pop si
pop es
pop dx
pop cx
pop ax
ret
2.解决除法溢出问题
应用举例:计算1000000/10(F4240H/0AH)
; 名称:divdw
; 功能:进行不会产生溢出的除法运算,被除数为 dword 型,除数为 word 型,结果为dword 型。
; 参数:(ax)=dword型数据的低 16位
; (dx)=dword型数据的高16位
; (cx)=除数
; 返回:(dx)=结果的高16 位,(ax)=结果的低 16位
; (cx)=余数
divdw:
push bx
push ax
mov ax,dx
mov dx,0
div cx ;1.先算高位的余数和商,结果放到dx和ax中
mov bx,ax ;将高位结果商(ax)放到bx中,后续放到dx中
pop ax ;2.再算低位的余数和商
div cx ;dx是高位的余数,和低位ax中进行除法运算
mov cx,dx ;dx中是低位的余数,按题目要求放到cx中
mov dx,bx ;
pop bx
ret
3.word 数值显示问题
编程,将data段中的数据以十进制的形式显示出来。
;名称:dtoc
;功能:将word型数据转变为表示十进制数的字符串,字符串以0为结尾符。
;参数:(ax)=word型数据
; ds:si指向字符串的首地址
;返回:无
dtoc_word:
push ax
push bx
push cx
push dx
push si
mov bx,0
div_loop:
mov dx,0
mov cx,10
div cx ;dx位商,ax为余数
add dx,'0'
push dx
inc bx
mov cx,ax
jcxz div_loop_out
jmp div_loop
div_loop_out:
mov cx,bx
mov si,0
set_data:
pop ds:[si]
inc si
loop set_data
pop si
pop dx
pop cx
pop bx
pop ax
ret
4 dword 数值显示代码
;名称:dtoc_dword
;功能:将dword 型数转变为表示十进制数的字符串,字符串以0为结尾符。
;参数:(ax)=dword型数据的低16位
; (dx)=dword型数据的高16位
; ds:si指向字符串的首地址
;返回:无
dtoc_dword:
push ax
push bx
push cx
push dx
push si
mov bx,0
dtoc_dword_div:
mov cx,10
call divdw
push cx
inc bx
cmp ax,0
jne dtoc_dword_div
cmp dx,0
jne dtoc_dword_div
mov si,0
mov cx,bx
dtoc_dword_set_data:
pop ds:[si]
add byte ptr ds:[si],'0'
inc si
loop dtoc_dword_set_data
pop si
pop dx
pop cx
pop bx
pop ax
ret
5.清除当前页面数据
;清空屏幕
clear_screen:
push ax
push cx
push es
push di
mov ax,0b800h
mov es,ax ;(es)=(0b800h)
mov cx,80*25 ;清屏总共需要写 80*25 个字符
mov di,0 ;初始化偏移地址为 0
clear_screen_loop: ;清屏
mov byte ptr es:[di],' ' ;将空格写入显存
mov byte ptr es:[di+1],0 ;将颜色属性写入显存
add di,2 ;偏移地址加 2
loop clear_screen_loop ;循环清屏
pop di
pop es
pop cx
pop ax
ret
6.字符串转大写
将包含任意字符,以0结尾的字符串中的小写字母转变成大写字母
data segment
db "Beginner's All-purpose Symbolic Instruction Code.",0
data ends
;名称:letterc
;功能:将以0结尾的字符串中的小写字母转变成大写字母
;参数:ds:si指向字符串首地址
letterc:
push si
push ax
letterc_label:
mov al,[si]
cmp al,0
je letterc_ok
inc si
cmp al,'a'
jb letterc_label
cmp al,'z'
ja letterc_label
add al,'A'-'a'
mov ds:[si-1],al
jmp letterc_label
letterc_ok:
pop ax
pop si
ret

浙公网安备 33010602011771号