小咒 发表于 2013-8-13 01:48:06

实验10答案中的一个问题

本帖最后由 小咒 于 2013-8-13 01:58 编辑

课题要求:
名称:show_str
功能:在指定的位置,用指定的颜色,显示一个用0结束的字符串。
参数:(dh)=行号(取值范围0~24);
(dl)=列号(取值范围0~79);
(cl)=颜色;
ds:si指向字符串的首地址。
返回:无。

想问一个问题,首先我们的要求是一个show_str的子程序来控制指定位置指定颜色的写入,0来表示结束
在课题的答案中会把ax bx si es进行一个push入栈,当子程序结束后把他们pop出栈然后再进行一个ret
这个操作我就不是很明白为什么这里要把这几个值push入栈呢?

自己代码如下:
assume cs:code,ds:data
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_str

mov ax,4c00h
int 21h
;段地址b8000h-b80a0第一行
show_str:mov ax,0b800h
mov es,ax;段地址放入es
mov ax,0a0h;计算行号
mul dh;计算段地址
mov bx,ax;段地址放入bx
mov ax,2h;计算列号
mul dl;计算列号
add bx,ax;bx指向偏移地址[行号列号数据]
mov ah,cl;颜色放入ah
mov ch,00h

s:mov cl,
jcxz s0
mov al,cl
mov es:,ax
inc si
add bx,2
jmp s;无条件跳转

s0:ret;取栈顶值放入ip 返回

code ends
end start
答案代码:
assume cs:code,ds:data
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_str

   mov ax,4c00h
   int 21h

;名称:show_str
;功能:在指定的位置,用指定的颜色,显示一个用0结束的字符串。
;参数:(dh)=行号(取值范围0~24);
;      (dl)=列号(取值范围0~79);
;      (cl)=颜色;
;      ds:si指向字符串的首地址。
;返回:无。

show_str:
   push ax
   push bx
   push es
   push si
   mov ax,0b800h
   mov es,ax
   mov ax,160
   mul dh
   mov bx,ax ;bx=160*dh
   mov ax,2
   mul dl      ;ax=dl*2
   add bx,ax   ;mov bx,(160*dh+dl*2)设置es:bx指向显存首地址
   mov al,cl   ;把颜色cl赋值al
   mov cl,0

show0:
   mov ch,
   jcxz show1    ;(ds:si)=0时,转到show1执行   
   mov es:,ch
   mov es:.1,al
   inc si      ;ds:si指向下一个字符地址
   add bx,2      ;es:bx指向下一个显存地址
   jmp show0

show1:
   pop si
   pop es
   pop bx
   pop ax
   ret

code ends
end start





牡丹花下死做鬼 发表于 2013-8-13 05:56:38

我想我这么回答你 比如CALL 要完成一个函数的调用 汇编不是会先自右向左吧函数的参数压栈吗等到调用时在出栈便是自左向右 栈是一个暂时存储数据的地方 这些参数一般都是压栈的
我也刚刚学到第十章 希望能帮到你如有错误望请见谅

小咒 发表于 2013-8-13 06:33:21

牡丹花下死做鬼 发表于 2013-8-13 05:56 static/image/common/back.gif
我想我这么回答你 比如CALL 要完成一个函数的调用 汇编不是会先自右向左吧函数的参数压栈吗等到调用时在出栈 ...

你说的这个意思我理解,但是答案中的是调用时把它们push入栈了,调用过后pop出栈了
而并非需要调用时才pop出栈
所以我才对这里的代码有疑问,要不就是我对代码的理解错误?

牡丹花下死做鬼 发表于 2013-8-13 06:38:35

小咒 发表于 2013-8-13 06:33 static/image/common/back.gif
你说的这个意思我理解,但是答案中的是调用时把它们push入栈了,调用过后pop出栈了
而并非需要调用时才p ...

但是答案中的是调用时把它们push入栈了,调用过后pop出栈了
压栈的数据使用过后当然要出栈啊 否则程序一大你需要多少个栈啊

小咒 发表于 2013-8-13 06:45:46

牡丹花下死做鬼 发表于 2013-8-13 06:38 static/image/common/back.gif
但是答案中的是调用时把它们push入栈了,调用过后pop出栈了
压栈的数据使用过后当然要出栈啊 否则程序一 ...

但是这个子程序中没有运用到任何的栈内数据,子程序中没有任何的出栈操作,相对于这个子程序而言,这样的入栈和出栈的操作不就变得没有意义?

牡丹花下死做鬼 发表于 2013-8-13 06:49:49

小咒 发表于 2013-8-13 06:45 static/image/common/back.gif
但是这个子程序中没有运用到任何的栈内数据,子程序中没有任何的出栈操作,相对于这个子程序而言,这样的 ...

pop si
   pop es
   pop bx
   pop ax
   ret这个不是出栈吗push ax
   push bx
   push es
   push si这个不是入栈吗
其实这代码 我前几天学的时候也没怎么看(*^__^*) 嘻嘻…… 应为学习汇编是为了理解C和学解密所以对这个{:5_96:}

小咒 发表于 2013-8-13 06:57:27

牡丹花下死做鬼 发表于 2013-8-13 06:49 static/image/common/back.gif
这个不是出栈吗这个不是入栈吗
其实这代码 我前几天学的时候也没怎么看(*^__^*) 嘻嘻…… 应为学习汇编是 ...

不是呀,你仔细看代码,我说的意思是这个入栈和出栈的操作在子程序中没有调用栈内数据,所以我认为对于这个子程序而言这个入栈和出栈的操作是没有意义的
以高级语言来编译程序我知道调用过程中先把参数push入栈有需要才会把参数pop出来,用完后再push进去

牡丹花下死做鬼 发表于 2013-8-13 07:10:32

小咒 发表于 2013-8-13 06:57 static/image/common/back.gif
不是呀,你仔细看代码,我说的意思是这个入栈和出栈的操作在子程序中没有调用栈内数据,所以我认为对于这 ...

介个......恕我以目前的知识 无法解释sorry~~~~(>_<)~~~~

小咒 发表于 2013-8-13 07:47:25

牡丹花下死做鬼 发表于 2013-8-13 07:10 static/image/common/back.gif
介个......恕我以目前的知识 无法解释sorry~~~~(>_

嗯,共同努力进步吧,估计也就我对这个有疑问而已
不知道这个答案是不是王爽老师自己写的,如果是的话我感觉他是想让我们更了解栈的原理,另外因为运用到call与ret也有对栈进行操作,所以给我们加深理解。
没有更好的解释的话我只能这样自行理解了{:5_92:}

牡丹花下死做鬼 发表于 2013-8-13 07:56:25

小咒 发表于 2013-8-13 07:47 static/image/common/back.gif
嗯,共同努力进步吧,估计也就我对这个有疑问而已
不知道这个答案是不是王爽老师自己写的,如果是的话我 ...

是啊 一起努力吧 只可惜快要暂离鱼C了 变成苦逼的高二党

281595933 发表于 2013-8-13 08:38:31

      楼主~!其实这个问题很简单啊,你想想如果一个程序要调用很多子程序,而且每个子程序里用到的寄存器都有差不多你怎么办,所以要在调用子程序之前先把先把相关的寄存器的值保存,调用完后再恢复,方便下个要调用的子程序取值。这跟C的调用函数差不多吧,所以养成这种习惯对以后学习有帮助的。。。

小咒 发表于 2013-8-13 08:40:39

牡丹花下死做鬼 发表于 2013-8-13 07:56 static/image/common/back.gif
是啊 一起努力吧 只可惜快要暂离鱼C了 变成苦逼的高二党

不错了高1的时候就有那么强的求知欲望,慢慢努力到大学了必成大器哟
我高1的时候还只会玩游戏呢,咱都已经是快要结婚的人了

兰陵啸天 发表于 2015-7-6 12:29:02

我想这应该是让我们形成一种习惯,保证用到的寄存器都恢复过来,不过如果这样理解的话,DX寄存器也应压栈再POP,因为里面用到了DH。

一个程序可能不止一个子程序,如果存在多个子程序调用到寄存器的行为,在子程序前都压栈,结束前都出栈,这样就不会影响到其他子程序对寄存器的使用,结果发生错误的几率将大大减少。

H.FF 发表于 2015-8-26 17:31:30

不知道为什么用debug调试说内存指令出错,但直接在cmd下运行程序就好好的,没有任何问题

H.FF 发表于 2015-8-26 17:47:54

答案的代码里面用到了ch,但是事先并没有保存,为什么不直接push cx顺便保存一下
页: [1]
查看完整版本: 实验10答案中的一个问题