汇编-模块化程序设计(子程序设计)
;计算data段中第一组数据的3次方, 结果保存在后面一组dword单元中 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 si,0 ;ds:si指向第一组word单元 mov di,16 ;ds:di指向第二组dword单元 mov cx,8 s:mov bx,[si] call cube ;调用子程序 mov [di],ax mov [di].2,dx add si,2 ;ds:si指向下一个word单元 add di,4 ;ds:di指向下一个dword单元 loop s mov ax,4c00h int 21h cube:mov ax,bx ;子程序 mul bx mul bx ret code ends end start
子程序-显示字符
;功能:在指定的位置,用指定的颜色,显示一个用0结束的字符串。 ;参数:(dh)=行号(取值范围0~24),(dl)=列号(取值范围0~79),(cl)=颜色, ;ds:si指向字符串的首地址 ;返回:无 ;应用举例:在屏幕的8行3列, 用绿色显示data段中的字符串。 assume cs:code data segment db 'Welcome to masm!',0 data ends code segment start:mov ax,data mov ds,ax mov si,0 ;字符串的首地址 mov dh,8 ;行号 mov dl,3 ;列号 mov cl,2 ;绿色 call show_str mov ax,4c00h int 21h show_str: ;子程序用到的寄存器一定要先保存 push ax push es push bx push bp mov ax,0B800h ;显存段地址 mov es,ax mov bl,cl ;bl保存颜色 ;计算偏移量 mov al,160 mul dh mov bp,ax mov al,2 mul dl add bp,ax ;计算出偏移量;bp显存偏移量 s:mov ch,0 mov cl,[si] ; 提取字符 jcxz s1 ;0字符返回 mov es:[bp],cl mov es:[bp+1],bl inc si add bp,2 jmp s s1:pop bp pop bx pop es pop ax ret code ends end start
防止溢出的除法运算
;名称:divdw ;功能:进行不会产生溢出的除法运算, 被除数为dword型, 除数为word型, 结果为dword型。 ;参数:(ax)=dword型数据的低16位,(dx) =dword型数据的高16位,(cx)=除数 ;返回:(dx)=结果的高16位,(ax)=结果的低16位,(cx)=余数 ;应用举例:计算1000000/10(F4240H/0AH)=商186A0=100000 assume cs:code data segment data ends code segment start: mov ax,4240h ;被除数低位 mov dx,000Fh ;被除数高位 mov cx,0Ah ;除数 call divdw mov ax,4c00h int 21h divdw: push bx push ax ;保存低16位 ;求int(H/N) mov ax,dx ;高16位值给ax mov dx,0 div cx ;(H/N)的商保存到ax中,(H/N)余数保存到dx中 mov bx,ax ;bx保存(H/N)的商 pop ax ;提取低16位 ;求[rem(H/N) *65536+L] /N ;*65536就是把数据左移16位,放到高位的意思 ;(H/N)余数在dx中(高位),就是rem(H/N) *65536 ;(H/N)余数在dx中,低位在ax中,就是rem(H/N) *65536+L div cx ;ax中保存[rem(H/N) *65536+L] /N的商 mov cx,dx ;返回余数 mov dx,bx ;(H/N)的商放到高位就是int(H/N) * 65536 ;X/N=int(H/N) *65536+[rem(H/N) *65536+L] /N=dx+ax pop bx ret code ends end start
word型数据转变为十进制数的字符串
;名称:dtoc ;功能:将word型数据转变为表示十进制数的字符串, 字符串以0为结尾符 ;参数:(a x) =word型数据 ;ds:si指向字符串的首地址 ;返回值:无 ;应用举例:编程,将数据12666以十进制的形式在屏幕的8行3列,用绿色显示出来。 ;在显示时我们调用本次实验中的第一个子程序show_str。 assume cs:code data segment db 10 dup(0) data ends code segment start: mov ax,12666 ;317A mov bx,data mov ds,bx mov si,0 call dtoc mov dh,8 mov dl,3 mov cl,2 mov si,0 ;字符串的首地址 call show_str mov ax,4c00h int 21h dtoc: ;将word型数据转变为表示十进制数的字符串, 字符串以0为结尾符 push dx push cx push ax push si push bx mov bx,0 ;bx保存字符总数 dt1:mov cx,10d ;d表示十进制,余数 mov dx,0 div cx ;ax保存商,dx保存余数 mov cx,ax ;把商给cx jcxz dt2 ;如果商等于0跳到dt2 add dx,30h ;把余数加上30h得到ASCII吗 push dx inc bx jmp dt1 dt2:add dx,30h push dx inc bx mov cx,bx ;循环次数 mov si,0 dt3:pop ax mov [si],al inc si loop dt3 mov al,0 mov [si],al ;保证0结尾 pop bx pop si pop ax pop cx pop dx ret show_str: ;子程序用到的寄存器一定要先保存 push ax push es push bx push bp mov ax,0B800h ;显存段地址 mov es,ax mov bl,cl ;bl保存颜色 ;计算偏移量 mov al,160 mul dh mov bp,ax mov al,2 mul dl add bp,ax ;计算出偏移量;bp显存偏移量 s:mov ch,0 mov cl,[si] ; 提取字符 jcxz s1 ;0字符返回 mov es:[bp],cl mov es:[bp+1],bl inc si add bp,2 jmp s s1:pop bp pop bx pop es pop ax ret ;返回 code ends end start
清屏
assume cs:code data segment data ends code segment start: call cls mov ax,4c00h int 21h cls: ;清屏 push bx push es push dx push cx mov bx,0b800h ;显存地址 0xb800 mov es,bx mov bx,0 mov cx,4000 ;文本模式显示25行,80字 即80*25*2 = 4000字节 s: mov dl,0 ;将NULL字符,即ASCII 0 放入低位 mov dh,0 ;将颜色 0 即 黑色 放入高位 mov es:[bx],dx add bx,2 loop s pop cx pop dx pop es pop bx ret code ends end start
延时子程序
delay:push ax ;延时子程序 push dx mov dx,3h ;循环次数,读者可以根据自己机器的速度调整循环次数 mov ax,0 sl:sub ax,1 sbb dx,0 cmp ax,0 jne sl cmp dx,0 jne sl pop dx pop ax ret
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
2020-08-11 C++ 日期与时间-ctime
2020-08-11 C++构造函数
2020-08-11 C++类的定义和封装
2020-08-11 C++访问控制限定符
2019-08-11 python-pillow图像处理