您的位置:首页 > 其它

x86汇编--(五)定位内存+栈的巧妙应用 温故知新

2016-04-04 11:27 204 查看
之前都是靠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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: