小属 发表于 2012-10-19 19:55:32

汇编语言课后题检测点3.2求教

第一个栈顶sp等于10H
第二个栈顶sp怎么是0h?

newu 发表于 2012-10-19 21:58:15

这里有答案自己看


补充内容 (2012-10-19 21:58):
检测点3.2

(1)补全下面的程序,使其可以将10000H-1000FH中的8个字,逆序拷贝到20000H-2000FH中。


mov ax,1000H

mov ds,ax

mov ax,2000H

mov ss,ax   

mov sp,10h   

push

push

pus

补充内容 (2012-10-19 21:59):
检测点3.2

(2)补全下面的程序,使其可以将10000H-1000FH中的8个字,逆序拷贝到20000H-2000FH中。

mov ax,2000H

mov ds,ax

mov ax,1000H

mov ss,ax   

mov sp,0   

pop

pop

pop [

我偷月亮的心 发表于 2012-10-20 12:55:17

二楼正解:'(:'(

空白 发表于 2012-10-20 19:38:59

看来 我也全答对了

空白 发表于 2012-10-20 19:41:24

你得搞清楚 入栈和出栈

小属 发表于 2012-10-20 22:12:02

向往未来 发表于 2012-10-19 21:58 static/image/common/back.gif
这里有答案自己看



{:5_109:}今天已经想明白了 不过仍然感谢,

yunfei77 发表于 2012-10-21 10:29:18

lyoal 发表于 2012-10-21 16:33:57

向往未来 发表于 2012-10-19 21:58 static/image/common/back.gif
这里有答案自己看



还好,我也这么作的。有个问题请教一下,在小甲鱼教程中有个将DS,CS,SS各段地址都设置为1000H,你的测试结果怎么样。我测试失败,报错。还有测试点中第一题的程序,虽说写对了,但是使用DEBUG测试时,在执行到 PUSH 时,报错,提示执行的是非法指令。怎么回事儿?求教。。。。

flower12355 发表于 2012-11-13 23:36:33

我也是刚走到这里,上网找到的笔记,自己也在理解
学习笔记:第三章   寄存器(内存访问)

1.字在内存中存储时,要用两个地址连续的内存单元来存放。字的低位字节存放在低地址单元中,高位字节存放在高地址单元中。我们将起始地址为n的字单元为n地址单元。

2.表示一个偏移地址为address的内存单元。
用mov指令要存放内存单元时,可以在mov指令中只给出单元的偏移地址,此时,段地址默认在ds寄存器中。
同样的,在debug中使用d命令和e命令(处理内存数据),只需给出单元的偏移地址,段地址默认在ds寄存器中;使用a命令,u命令和t命令(处理指令),只需给出单元的偏移地址,段地址默认在cs寄存器中;

3.传送指令MOV(Move Instruction):
传送指令是使用最频繁的指令,它相对于高级语言里的赋值语句。
指令格式: MOV dest, src
指令功能:把一个字节或字的操作数从源地址src传送至目的地址dest。指令执行后,目的操作数的值被改变,而源操作数的值不变。在存储单元是该指令的一个操作数时,该操作数的寻址方式可以是任意一种存储单元寻址方式。
MOV指令是采用寻址方式最多的指令,用我们约定的符号可以表达如下:   
MOV reg/mem,imm    ;立即数送寄存器或主存
MOV reg/mem/seg,reg;寄存器送寄存器(包括段寄存器)或主存
MOV reg/seg,mem    ;主存送寄存器(包括段寄存器)
MOV reg/mem,seg    ;段寄存器送主存或寄存器
对MOV指令有以下几条具体规定,其中有些规定对其它指令也同样有效。
(1)两个操作数的数据类型要相同,要同为8位、16位或32位;如:MOVBL, AX等是不正确的;
(2)在内存和寄存器之间传送字类型数据时,高地址单元和高8位寄存器,低地址单元和低8位寄存器相对应;
(3)两个操作数不能同时为段寄存器,如:MOVES, DS等;
(4)两个操作数不能同时为存储单元,如:MOVVARA, VARB等,其中VARA和VARB是同数据类型的内存变量;
(5)代码段寄存器CS不能为目的操作数,但可作为源操作数,如:指令MOVCS, AX等不正确,但指令MOVAX, CS等是正确的;
(6)指令指针IP,不能作为MOV指令的操作数;
(7)立即数不能直接传给段寄存器,如:MOVDS, 100H等;
(8)立即数不能作为目的操作数,如:MOV100H, AX等;
(9)由于指定的寄存器有明确的字节或字类型,所以对应的立即数也必须分别是字节或字;但在涉及存储器单元时,指令中给出的立即数可以理解为字,也可以理解为字节,此时必须显式指明。为了区别是字节传送还是字传送,可用汇编操作符byte ptr(字节)和word ptr(字)指定;
(10)对于不能直接传送的数据,如(2)(3)(6),可以使用通用寄存器作为中转站;不能用传送指令MOV修改寄存器CS和IP,可使用转移指令JMP设置它们的值。

4.堆栈:
      堆栈是一个“先进后出”的主存区域,位于堆栈段中,使用SS段寄存器记录其段地址。堆栈只有一个出口,即当前栈顶。栈顶是地址较小的一端(低端),它用堆栈指针寄存器SP指定。
堆栈有两种基本操作,对应有两条基本指令:进栈指令PUSH和出栈指令POP。
任意时刻,SS:SP指向栈顶元素。PUSH指令和POP指令执行时,CPU从SS和SP中得到栈顶的地址。
用栈来暂存以后需要恢复的寄存器的内容时,寄存器出栈的顺序和入栈时相反。
PUSH,POP实质上就是一种内存传送指令,可以在寄存器和内存之间传送数据,与MOV指令不同的是,PUSH和POP指令访问的内存单元的地址不是在指令中给出的而是有SS:SP指出的。同时,PUSH 和POP指令还要改变SP中的内容。

5.进栈指令:
指令格式: PUSHsrc
指令功能:把一个字操作数存入堆栈顶部,同时使堆栈指针SP减2。
执行顺序:SP的值先减1,操作数的高位字节送入当前SP所指内存单元中;然后SP的值再减1,操作数的低位字节送入当前SP所指内存单元中。
说明:(1)PUSH入栈指令可以使用的源操作数src有:寄存器(通用寄存器,地址指针,变址寄存器,段寄存器),存储器。只有立即数不允许入栈。
(2)堆栈操作的对象只能是字操作数,进栈时,低字节存放于低地址,高字节存放在高地址,SP相应向低地址移动两个字节单元。
(3)栈为空时,SS:SP指向栈空间最高地址单元的下一个单元。如我们将10000H-1000FH这段空间当作栈。初始状态栈是空的,此时,SS = 1000H,SP = 0010H。
理解方式有两种:一是我们可以假设栈中有只有一个元素,则SP = 000EH。现在将这个元素出栈,则 SP = SP + 2,变成SP = 0010H。二是因为当栈为空时,栈中没有元素,也就不存在栈顶元素,所以SS:SP只能指向栈的最底部字单元下面的单元,该单元的偏移地址为栈最底部的字单元的偏移地址+2。栈的最底部字单元的地址为1000:000E,所以当栈空时,SP = 0010H。

6.标志进栈指令:
指令格式:PUSHF
指令功能:把标志寄存器PSW中的内容存入堆栈顶部,同时使堆栈指针SP的值减2。
执行顺序:SP的值先减1,PSW的高位字节送入当前SP所指内存单元中;然后SP的值再减1,操作数的低位字节送入当前SP所指内存单元中。
说明:默认规定了标志寄存器和和当前堆栈栈顶空间。

7.出栈指令:
指令格式: POPDST栈顶的一个字传送至指定的目的操作数,然后堆栈指针SP加2。目的操作数应为字操作数,
指令功能:把当前SP所指向堆栈顶部的一个字弹出送入指定的目的操作数,同时使堆栈指针SP加2。
执行顺序:先将SP所指的栈顶单元内容送入DST低位字节单元,SP的值加1;然后将当前SP所指的栈顶单元内容送入DST高位字节单元,SP的值再加1。
说明:(1)PUSH入栈指令可以使用的目的操作数dest有:寄存器(通用寄存器,地址指针,变址寄存器,段寄存器),存储器。立即数和段寄存器CS不允许作为目的操作数。
(2)堆栈操作的对象只能是字操作数,字从栈顶弹出时,低地址字节送低字节,高地址字节送高字节,SP相应向高地址移动两个字节单元。
(3)出栈后,SS:SP指向新的栈顶。POP操作前的栈顶元素依然存在,但是,它已经不在栈中,当再次执行PUSH等入栈指令后,新的指令将其覆盖。

8.标志出栈指令:
指令格式:POPF
指令功能:从堆栈顶部弹出两个字节送到标志寄存器PSW中,同时使堆栈指针SP的值加2。
执行顺序:先将SP所指的栈顶单元内容送入PSW的低位字节单元,SP的值加1;然后将当前SP所指的栈顶单元内容送入PSW的高位字节单元,SP的值再加1。
说明:默认规定了标志寄存器和和当前堆栈栈顶空间。

9.栈顶超界的问题:
当栈满的时候再使用PUSH指令入栈,或栈空的时候再使用POP指令出栈,都会发生栈顶超界的问题。
      8086CPU不保证我们对栈的操作不会超界。所以我们在编程的时候要自己操心栈顶超界的问题,要根据可能用到的最大栈空间,来安排栈的大小,防止入栈的数据太多而导致的超界;执行出栈操作时也要注意,以防止栈空的时候继续出栈而导致的超界。
      PUSH,POP等栈操作指令,修改的只是SP。因为逻辑段的最大容量为64KB,所以栈顶的变化范围最大为0-FFFFH。从栈空的时候SP=0,一直入栈,直到栈满使SP=0;如果再次入栈,栈顶将环绕,覆盖了原来栈中的内容。所以一个栈段的容量最大为64KB。

10.段的综述:
      一段内存,可以既是代码的存储空间,又是数据的存储空间,还可以是栈空间,也可以什么都不是。关键在于CPU中寄存器的设置,即当CS:IP指向该处时,CPU将其视为代码;当SS;SP指向该处时,CPU将其视为栈;当DS指向该处时,CPU将其视为普通数据。
      Debug的T命令在执行修改段寄存器SS的指令时,下一条指令也紧接着被执行。

11.检测点3.2
(1)补全下面的程序,使其可以将10000H-1000FH中的8个字,逆序拷贝到20000H-2000FH中。
mov ax, 1000H
mov ds, ax
( mov ax, 2000H )
( mov ss, ax )
( mov sp, 0010H );此时栈空
push
push
push
push
push
push
push
push

(2)补全下面的程序,使其可以将10000H-1000FH中的8个字,逆序拷贝到20000H-2000FH中。
mov ax, 2000H
mov ds, ax
( mov ax, 1000H )
( mov ss, ax )
( mov sp, 0000H );此时栈满
pop
pop
pop
pop
pop
pop
pop
pop

菜鸟一个a 发表于 2013-12-25 21:05:20

学习学习再学习

dlzhwm 发表于 2014-1-5 22:28:34

9#正点,学习班在学习。:funk:

lms99251 发表于 2014-1-9 14:07:22

lyoal 发表于 2012-10-21 16:33 static/image/common/back.gif
还好,我也这么作的。有个问题请教一下,在小甲鱼教程中有个将DS,CS,SS各段地址都设置为1000H,你的测试结 ...

1000H是不是被其他程序占用了呀,还有程序写对了吗

lms99251 发表于 2014-1-9 14:09:13

弄清楚栈的后入先出,你就明白了

管道超人 发表于 2014-9-23 11:22:16

1

隐s丶 发表于 2015-3-5 15:32:49

绕来绕去 总有种似懂非懂的感觉
页: [1]
查看完整版本: 汇编语言课后题检测点3.2求教