鱼C论坛

 找回密码
 立即注册
查看: 9501|回复: 14

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

[复制链接]
发表于 2012-10-19 19:55:32 | 显示全部楼层 |阅读模式
1鱼币
第一个栈顶sp等于10H
第二个栈顶sp怎么是0h?

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 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 [0]  

push [2]  

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 [e]  

pop [c]  

pop [
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-10-20 12:55:17 | 显示全部楼层
二楼正解:'(:'(
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-10-20 19:38:59 | 显示全部楼层
看来 我也全答对了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-10-20 19:41:24 | 显示全部楼层
你得搞清楚 入栈和出栈
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2012-10-20 22:12:02 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

头像被屏蔽
发表于 2012-10-21 10:29:18 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-10-21 16:33:57 | 显示全部楼层
向往未来 发表于 2012-10-19 21:58
这里有答案自己看

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

使用道具 举报

发表于 2012-11-13 23:36:33 | 显示全部楼层
我也是刚走到这里,上网找到的笔记,自己也在理解
学习笔记:第三章   寄存器(内存访问)

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

2.[address]表示一个偏移地址为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位;如:MOV  BL, AX等是不正确的;  
(2)在内存和寄存器之间传送字类型数据时,高地址单元和高8位寄存器,低地址单元和低8位寄存器相对应;
(3)两个操作数不能同时为段寄存器,如:MOV  ES, DS等;
(4)两个操作数不能同时为存储单元,如:MOV  VARA, VARB等,其中VARA和VARB是同数据类型的内存变量;
(5)代码段寄存器CS不能为目的操作数,但可作为源操作数,如:指令MOV  CS, AX等不正确,但指令MOV  AX, CS等是正确的;
(6)指令指针IP,不能作为MOV指令的操作数;
(7)立即数不能直接传给段寄存器,如:MOV  DS, 100H等;
(8)立即数不能作为目的操作数,如:MOV  100H, 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.进栈指令:
指令格式: PUSH  src
指令功能:把一个字操作数存入堆栈顶部,同时使堆栈指针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.出栈指令:
指令格式: POP  DST栈顶的一个字传送至指定的目的操作数,然后堆栈指针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 [0]
push [2]
push [4]
push [6]
push [8]
push [A]
push [C]
push [E]

(2)补全下面的程序,使其可以将10000H-1000FH中的8个字,逆序拷贝到20000H-2000FH中。
mov ax, 2000H
mov ds, ax
( mov ax, 1000H )
( mov ss, ax )
( mov sp, 0000H );此时栈满
pop [E]
pop [C]
pop [A]
pop [8]
pop [6]
pop [4]
pop [2]
pop [0]
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-12-25 21:05:20 | 显示全部楼层
学习学习再学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-1-5 22:28:34 | 显示全部楼层
9#正点,学习班在学习。:funk:
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-1-9 14:07:22 | 显示全部楼层
lyoal 发表于 2012-10-21 16:33
还好,我也这么作的。有个问题请教一下,在小甲鱼教程中有个将DS,CS,SS各段地址都设置为1000H,你的测试结 ...

1000H是不是被其他程序占用了呀,还有程序写对了吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-1-9 14:09:13 | 显示全部楼层
弄清楚栈的后入先出,你就明白了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-9-23 11:22:16 | 显示全部楼层
1
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-3-5 15:32:49 | 显示全部楼层
绕来绕去 总有种似懂非懂的感觉
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-26 11:51

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表