汇编语言学习

来源:互联网 发布:阿里云禁止ip访问网站 编辑:程序博客网 时间:2024/04/30 11:41

以下代码为自己实现,未拿书本做任何的参考,思路有不对或者不到位的地方欢迎大家指出,由于是新人,代码注解难免繁杂,望见谅!

assume ds : datasg, cs : codesg, ss : stacksg
;show_ptr : 接受参数,在指定行,指定列显示指定的颜色
;dh : 行
;dl : 列
;cl : 颜色
;2017/8/27
datasg segment
db 'Welcome to masm!', 0
datasg ends


stacksg segment
dw 0, 0, 0, 0, 0, 0, 0, 0
stacksg ends


codesg segment
start :
mov ax, datasg
mov ds, ax


mov ax, stacksg
mov ss, ax
mov sp, 10h


mov dh, 8   ;传递参数,行,0~24
mov dl, 64    ;传递参数,列,0~79
mov cl, 2    ;显示的颜色,黑底绿字


mov bx, 0
mov si, 0
mov di, 0

call show_str     ;将mov ax, 4c00h的ip入栈


mov ax, 4c00h
int 21h


show_str :
mov bx, 0B800H  ;显存地址
mov es, bx


mov ax, 0           ;内容清零mov al, 0A0H   ;存放基地址,做八位乘法,八位寄存器乘法乘数默认放在al中
mul dh                 ;乘法结果保存在ax中,ax的结果用来定位显示在第几行
mov dh, 0           ;高八位清零,dx = 0003
add ax, dx         ;定位要显示的字符串首字母地址,行+列,dx寄存器可以释放
mov bx, ax

s0 : 
mov ch, 0
push cx                ;cl为要显示的颜色
mov cl, ds : [si]
mov ch, 0
jcxz ok               ;判断字符串是否结束



;mov es : [ax + di], cl     ;放入显存,字符ASCII码放在低位字节
mov es : [bx + di], cl
pop cx             ;颜色出栈,push和pop只能是16位寄存器
                        ;为什么不是存放颜色属性的cl入栈???因为push和pop指令只能按字单元形式访堆栈
;mov es : [ax + di + 1], cl    ;错误,[bx + di(si) + idata],不要想当然
mov es : [bx + di + 1], cl     ;将显示的颜色属性放入显存,字符颜色属性放在高位字节
inc si
add di, 2


jmp short s0   ;代替loop循环,因前面已经有结束循环的判断


ok : 
ret    ;ip出栈


codesg ends
end start




assume ds : datasg, cs : codesg, ss : stacksg

;show_ptr : 接受参数,在指定行,指定列显示指定的颜色
;dh : 行
;dl : 列
;cl : 颜色
;2017/8/27
datasg segment
db 'Welcome to masm!', 0
datasg ends


stacksg segment
dw 0, 0, 0, 0, 0, 0, 0, 0
stacksg ends


codesg segment
start :
mov ax, datasg
mov ds, ax


mov ax, stacksg
mov ss, ax
mov sp, 10h


mov dh, 8   ;传递参数,行,0~24
mov dl, 64    ;传递参数,列,0~79
mov cl, 2    ;显示的颜色,黑底绿字


mov bx, 0
mov si, 0
mov di, 0

call show_str     


mov ax, 4c00h
int 21h


show_str :
mov bx, 0B800H  ;显存地址
mov es, bx


mov ax, 0           ;内容清零mov al, 0A0H   ;存放基地址,做八位乘法,八位寄存器乘法乘数默认放在al中
mul dh                 ;乘法结果保存在ax中,ax的结果用来定位显示在第几行
mov dh, 0           ;高八位清零,dx = 0003
add ax, dx         ;定位要显示的字符串首字母地址,行+列,dx寄存器可以释放
mov bx, ax

s0 : 
mov ch, 0
push cx                ;cl为要显示的颜色
mov cl, ds : [si]
mov ch, 0
jcxz ok               ;判断字符串是否结束



;mov es : [ax + di], cl     ;放入显存,字符ASCII码放在低位字节
mov es : [bx + di], cl
pop cx             ;颜色出栈,push和pop只能是16位寄存器
                        ;为什么不是存放颜色属性的cl入栈???因为push和pop指令只能按字单元形式访堆栈
;mov es : [ax + di + 1], cl    ;错误,[bx + di(si) + idata],不要想当然
mov es : [bx + di + 1], cl     ;将显示的颜色属性放入显存,字符颜色属性放在高位字节
inc si
add di, 2


jmp short s0   


ok : 
ret    


codesg ends

end start

以上代码有以下几点可以总结:

1.mul指令的运用,八位寄存器做乘法,结果存放在ax中,其中一个乘数默认放在al(底八位寄存器),另一个乘数可以放在八位寄存器或者内存单元,需要注意的是八位寄存器也可以是高八位的寄存器,比如dh.

举例如下:

mov al, 10

mov dh, 15

mul dh

经过调试发现是没有提示错误的

2.push和pop指令

两个指令只能以字单元形式(两个字节)形式访问栈,因此上面代码虽然颜色属性放在cl中,但仍然要转换为16位再入栈,出栈亦如此,代码刚开始实现时候是写了push cl,和pop cl,后来发现一直保存,所以改为push cx和pop cx

3.[bx + si(di) + idata]的格式

要严格按照格式,其中的bx不能换做其他寄存器,刚开始用的ax寄存器发现报错,另外格式si(di)和idata的顺序也不能调换,调换也会报错



原创粉丝点击