之前都是靠ds:[bx]或者[bx]来直接定位内存的
之后知道了SI和DI这两个寄存器,这样定位内存的方法就更加灵活了
SI和DI是与bx功能差不多只是不能像BX一样拆分成bl和bh
同时,还有这样的方式:mov ax,ds:[bx+idata]
idata是一个数,可以自己来定,这种用法在程序中是否有用,如下
assume cs:codesg,ds:datasg
datasg segment
db 'Basic'
db 'Linux'
datasg ends
codesg segment
start:
mov ax,datasg
mov ds,ax
mov bx,0
mov cx,5
s: mov al,ds:[bx]
mov ah,ds:[bx+5]
or al,00100000b ;转换为小写
and ah,11011111b ;转换为大写
mov ds:[bx],al
mov ds:[bx+5],ah
add bx,1
loop s
mov ax,4c00h
int 21h
codesg ends
end start
下面是嵌套的循环,不过程序执行有问题,就是debug发现无限循环
assume cs:codesg,ds:datasg
datasg segment
db 'acfil '
db 'acfil '
db 'acsea '
db 'acopt '
datasg ends
codesg segment
start:
mov ax,datasg
mov ds,ax
mov bx,0
mov cx,4
s0: mov si,0
;si定位列
mov cx,3
s: mov al,[bx+si]
and al,11011111b ;小写变大写
mov [bx+si],al ;覆盖原来的小写
inc si
loop s
;bx定位行
add bx,16
loop s0
mov ax,4c00h
int 21h
codesg ends
end start
debug就会知道:
(1)内循环退出,CX的值是0
(2)执行外面的loop s0,CX-1。由于CX之前变0了,CX-1变为0XFFFF,
(3)进入内循环,又执行(1)
无限循环bug - -
------------------------------栈是个好东西-----------------------------------------
上面的程序bug通过栈暂存cx来解决,如下:
assume cs:codesg,ds:datasg,ss:stacksg
datasg segment
db 'acfil '
db 'acfil '
db 'acsea '
db 'acopt '
datasg ends
stacksg segment
dw 0,0,0,0,0,0,0,0
stacksg ends
codesg segment
start:
mov ax,stacksg
mov ss,ax
mov sp,16
mov ax,datasg
mov ds,ax
mov bx,0
mov cx,4
s0: push cx ;把cx的值保存起来
mov si,0
;si定位列
mov cx,5
s: mov al,[bx+si]
and al,11011111b ;小写变大写
mov [bx+si],al ;覆盖原来的小写
inc si
loop s
;bx定位行
add bx,16
pop cx ;恢复cx外层循环的值
loop s0
mov ax,4c00h
int 21h
codesg ends
end start
0 0 栈太巧妙了,实际上各种编程语言都是这样的机制来调用函数吖、进行循环吖之类的(づ ̄ 3 ̄)づ
以后多用栈啊( •̀ ω •́ )y