|
主题 : : 一个有趣的现象,入栈了不会出栈!!! [已解决] |
回复[ 9次 ]
点击[ 490次 ] | |
|
|
|
|
[帖 主]
[ 发表时间:2012-04-09 13:09 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:5
注册日期:2012-03-22 15:34 |
;实验10.1的问题,有详细注释,显示后的颜色有点问题,麻烦各位看看。
;小疑问:程序中没有使用栈,但是没有错误,难道内存自动定义一个栈?
;在s2下面还有一个小错误。。。整个程序还存在两个警告!!!
assume cs:code
data segment
db 'Welcome to masm!',0
data ends
;stack segment ;原代码中没有定义栈
; db 16 dup (0)
;stack ends
code segment
start: mov dh,8 ;显存的行
mov dl,3 ;显存的列
mov cl,2 ;颜色
mov ax,data
mov ds,ax
;mov ax,stack ;原代码中没有定义栈
;mov ss,ax
;mov sp,16
mov si,0
mov bx,0 ;自己加的寄存器,貌似原代码没有bx
call show ;跳转指令
mov ax,4c00h ;返回指令
int 21h
show:
mov ax,0B800h ;显存段地址
mov es,ax
mov al,160 ;每行160个字节
mul dh ;8位运算,储存在ax中
mov bx,ax ;寄存相乘后的结果,作为es的偏移地址使用
add bx,160 ;加160是因为显示器貌似不是从第一行开始显示的
s2: push cl ;cl入栈是为了保存颜色
mov ch,0 ;让ch赋值为0
mov cl,ds:[si] ;把数据段中的字节赋值到cl中
jcxz s1 ;cx不为0,则继续向下运行,否则跳转到s1
mov es:[bx + 4],cl ;把cl赋值到显存
pop cl ;将保存的颜色出栈,准备使用 (但是貌似没有出栈,运行后的颜色各不相同)
mov ch,cl; mov ch,2; ;颜色保存到ch中(想不通为什么这里写mov ch,2就是对的,这样写就是错的。。。)
mov es:[bx + 5],ch ;ch赋值给高位(高位保存颜色,低位保存字节)
inc si
add bx,2
loop s2 ;s2循环
s1: ret ;跳到返回指令处
code ends
end start | | |
|
|
|
|
[第1楼]
[ 回复时间:2012-04-09 23:37 ]
[引用]
[回复]
[ top ] | |
荣誉值:405
信誉值:0
注册日期:2008-01-19 14:51 |
"push cl"这条指令的语法有问题,栈是字操作,不可以是字节操作。 | | |
|
|
|
|
[第2楼]
[ 回复时间:2012-04-09 23:38 ]
[引用]
[回复]
[ top ] | |
荣誉值:405
信誉值:0
注册日期:2008-01-19 14:51 |
|
|
|
|
|
[第3楼]
[ 回复时间:2012-04-09 23:44 ]
[引用]
[回复]
[ top ] | |
荣誉值:405
信誉值:0
注册日期:2008-01-19 14:51 |
“;小疑问:程序中没有使用栈,但是没有错误,难道内存自动定义一个栈? ”
栈的定义,其实就是设置栈段寄存器的值,我们的程序定义栈段也就是将栈段寄存器的值设置为我们程序分配好的那段栈空间,如果我们的程序中没有定义栈段,那么栈空间就是当前栈段寄存器指向的栈空间。如果对栈进行操作就是对这段空间进行操作。 | | |
|
|
|
|
[第4楼]
[ 回复时间:2012-04-10 12:22 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:5
注册日期:2012-03-22 15:34 |
回复:[第3楼]
------------------
感谢楼上的回答,我修改的程序如下:
麻烦看下思路还有没有问题,刚开始学子程序,可能在格式上会有些欠佳。
assume cs:code
data segment
db 'Welcome to masm!',0
data ends
code segment
start: mov dh,8 ;显存的行
mov dl,3 ;显存的列
mov cl,2 ;颜色
mov ax,data
mov ds,ax
mov si,0
call show ;跳转指令
mov ax,4c00h ;返回指令
int 21h
show:
mov bx,0
push cx
mov ax,0B800h ;显存段地址
mov es,ax
mov al,160 ;每行160个字节
mul dh ;8位运算,储存在ax中
mov bx,ax ;寄存相乘后的结果,作为es的偏移地址使用
add bx,160 ;加160是因为显示器貌似不是从第一行开始显示的
dec dl ;列减1
mov al,2 ;做乘法
mul dl ;第三列在第四字节上,(3-1)*2 = 4
add bx,ax ;bx作为显示第一个字节的偏移地址
s2: mov ch,0 ;让ch赋值为0
mov cl,ds:[si] ;把数据段中的字节赋值到cl中
jcxz s1 ;cx不为0,则继续向下运行,否则跳转到s1
mov es:[bx],cl ;把cl赋值到显存
pop cx ;将保存的颜色出栈,准备使用 (但是貌似没有出栈)
mov es:[bx + 1],cl ;cl赋值给高位(高位保存颜色,低位保存字节)
inc si ;数据段中的偏移地址加1
add bx,2 ;显存中偏移地址加2
push cx ;cx入栈,循环了以后出栈
jmp s2 ;s2循环
s1: pop cx ;没有写这句话,栈中还有其他数据,所以先出来的不是IP
ret ;跳到返回指令处
code ends
end start | | |
|
|
|
|
[第5楼]
[ 回复时间:2012-04-10 23:04 ]
[引用]
[回复]
[ top ] | |
荣誉值:405
信誉值:0
注册日期:2008-01-19 14:51 |
|
|
|
|
|
[第6楼]
[ 回复时间:2012-04-10 23:19 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:5
注册日期:2012-03-22 15:34 |
回复:[第5楼]
------------------
再问个栈的问题,如果是内存分配了一个空间做栈,那是不是跟在data下呢?我觉得不是,因为跟在data下,入栈太多可能导致要冲掉原来数据,所以内存肯定分配了一个安全区域,但知道在哪里么? | | |
|
|
|
|
[第7楼]
[ 回复时间:2012-04-10 23:27 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:5
注册日期:2012-03-22 15:34 |
所以SS和DS要不同,就不会导致栈出现溢出而冲掉data的数据了,这样理解对吧? | | |
|
|
|
|
[第8楼]
[ 回复时间:2012-04-11 00:09 ]
[引用]
[回复]
[ top ] | |
荣誉值:405
信誉值:0
注册日期:2008-01-19 14:51 |
这个要看程序加载的时候栈段寄存器的值是如何设置的。 | | |
|
|
|
|
[第9楼]
[ 回复时间:2014-02-17 14:21 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:5
注册日期:2012-03-22 15:34 |
此贴由 贴主 于 [ 2014-02-17 14:21 ] 结贴。 结贴原因:问题已解决 | | |