汇编网首页登录博客注册
jiajiade01的学习博客
博客首页博客互动【做检测题】论坛求助

我的博客

个人首页 |  我的文章 |  我的相册 |  我的好友 |  最新访客 |  文章收藏 |  论坛提问 |  友情链接 |  给我留言  
图片载入中
学习动态
最新留言
友情链接

[2009-01-20 00:09] 王爽 《汇编语言》    实验5

编写、调试具有多个断的程序
这一章的内容较少,有些知识需要在实践中掌握。这个实验,既是实验,也是学习内容。必须完成这个实验,才能继续向下学习。
  (1)将下面的程序编译连接,用Debug加载、跟踪,然后回答问题:

assume cs:code,ds:data,ss:stack

data segment
    dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
data ends

stack segment
    dw 0,0,0,0,0,0,0,0    ;10H 
stack ends

code segment
start: mov ax,stack    ;栈段
       mov ss,ax
       mov sp,16       ;10H

       mov ax,data     ;数据段
       mov ds,ax       

       push ds:[0]     
       push da:[2]
       pop ds:[2]
       pop ds:[0]      

       mov ax,4c00h
       int 21h

code ends
end start

①CPU执行程序,程序返回前,data段中的数据为多少?
    覆盖后并没有使原数据段中的内容发生改变.
②CPU执行程序,程序返回前,cs=code 、ss=stack 、ds=data
③设程序加载后,code段的段地址为X,则data段的段地址为(X-1-1)stack段的段地址为(X-1)


(2)将下面的程序编译连接,用Debug加载、跟踪,然后回答问题:

assume cs:code,ds:data,ss:stack

data segment
    dw 0123h,0456h     ;此段实际占用16字节.
data ends

stack segment
    dw 0,0             ;此段实际占用16字节. 
stack ends

code segment
start: mov ax,stack    ;栈段
        mov ss,ax
       mov sp,16       ;10H

       mov ax,data     ;数据段
        mov ds,ax       

       push ds:[0]     
       push da:[2]
       pop ds:[2]
       pop ds:[0]      

       mov ax,4c00h
       int 21h

code ends
end start

①CPU执行程序,程序返回前,data段中的数据为多少?
    没变
②CPU执行程序,程序返回前,cs=code 、ss=stack 、ds=data
③设程序加载后,code段的段地址为X,则data段的段地址为(X-1-1)stack段的段地址为(X-1)
④对于如下定义的段:
name segment
...
name ends
如果段中的数据占N个字节,则程序加载后,该段实际占有的空间为[(N÷16取整)+1]×16个, 其中N为10进制数,如果是N是16进制数则为:[(N÷10取整)+1]×10(H)个


(3)将下面的程序编译连接,用Debug加载、跟踪,然后回答问题:

assume cs:code,ds:data,ss:stack

code segment
start: mov ax,stack    
       mov ss,ax
       mov sp,16
       
       mov ax,data     
       mov ds,ax       

       push ds:[0]     
       push ds:[2]
       pop ds:[2]
       pop ds:[0]      

       mov ax,4c00h
       int 21h
code ends

data segment
    dw 0123h,0456h     
data ends

stack segment
    dw 0,0             
stack ends

end start


①CPU执行程序,程序返回前,data段中的数据为多少?
没变
②CPU执行程序,程序返回前,cs=code,ss=stack,ds=data
③设程序加载后,code段的段地址为X,则data段的段地址为(X+3)stack段的段地址为(X+4)


(4)如果将(1)、(2)、(3)题中的最后一条伪指令"end start"改为"end"(也就是说,不指明程序的入口),则哪个程序仍然可以正确执行?请说明原因.
第(3)题可以正确的执行,因为程序被加载后,cs:ip指向的就是程序的首条指令,可以说原题中的标号"start"本身就是多余的.



(5)程序如下,编写code段中的代码,将a段和b段中的数据依次相加,将结果存到c段中.

也许是我没理解题意吧,我就按着我所理解的题意编写吧,那就是(c:[0])=((a:[0])+(b:[0])),按照这个意思依次存放在c段中.再有,db没有见过,按照dw(dword)是定义字型数据,那么推断db(dbyte)就是定义字节型数据吧. 补完这个程序我觉得很别扭,下来再仔细看看研究研究.

assume cs:code

a segment
    db 1,2,3,4,5,6,7,8     ;db是定义字节数据吧
a ends

b segment

    db 1,2,3,4,5,6,7,8
b ends

c segment
    db 0,0,0,0,0,0,0,0
c ends

code segment
start:mov cx,8
    s:mov ax,a
      mov ds,ax
      mov ax,c
      mov es,ax
      mov bx,0
      mov dl,ds:[bx]
      mov es:[bx],dl
      mov ax,b
      mov ds,ax
      mov dl,ds:[bx]
      add es:[bx],dl
      inc bx
      loop s

mov ax,4c00h
int 21h

code ends
end start

也可以用栈的方式经过两次循环达到目的,但是有点麻烦.



(6)程序如下,编写code段中的代码,用push指令将a段中的前8个字型数据逆序存储到b段中.

assume cs:code

a segment
    dw 1,2,3,4,5,6,7,8,9,0ah,0bh,0ch,0dh,0eh,0fh,0ffh
a ends

b segment
    dw 0,0,0,0,0,0,0,0
b ends

code segment
start:mov ax,a
      mov ds,ax
      mov ax,b
      sub ax,1        ;防止超界,程序下面有说明.
      mov ss,ax
      mov sp,20H
      mov bx,0
      mov cx,8
    s:mov ax,[bx]
      push ax
      inc bx
      inc bx
      loop s
              
      mov ax,4c00h
      int 21h

code ends
end start

对于 sub ax,1 的思考:我以前做实验发现,栈顶之上还有个栈顶(这是我自己的比喻),不管栈如何变化,它们始终处于栈顶之上,我称它们为中转站,这里保存的是有个入栈命令和一个我不明白的命令,他们之上就是cs:ip和ax,bx的内容,它们在栈操作时暂存和送出相关寄存器内容,这些数据是连续存放的,如果发生栈顶超界(对于他们来说)数据就不能连续摆放了,这时系统就会发生错误,比如中转站中的数据存放到ss:0处的时候继续存放的话,那么后继的数据应该就会摆放在ss:ffff处了,数据不是连续摆放了,这时就会出错,sub ax,1就是为了防止这种错误出现.以我现在所学的知识还不能完全解释这个问题,我想随着课程的进行,我一定可以完全解释这个问题的.
评论次数(5)  |  浏览次数(736)  |  类型(汇编作业) |  收藏此文  | 

[  crazyman   发表于  2009-01-20 11:57  ]

如果段中的数据占N个字节,则程序加载后,该段实际占有的空间为[(N÷16取整)+1]×16个, 其中N为10进制数,如果是N是16进制数则为:[(N÷10取整)+1]×10(H)个 
======================
不全面,假如N为16的整数倍就不用+1了。

[  crazyman   发表于  2009-01-20 12:05  ]

看了第(6)题,感觉博主考虑的还挺仔细,不过楼主考虑的问题其实只会出现在我们debug过程,如果直接运行,是不会有中断程序在运行过程来使用当前栈,也就不会产生越界,数据的个数正好对应。
如果是debug下T单步去跟踪,观察运行结果,博主的这个做法就保证了单步过程后数据的正确性了。

博主这么细心确实不错。

[  jiajiade01   发表于  2009-01-20 17:40  ]

谢谢老师的鼓励,热盼您经常指导.

不全面,假如N为16的整数倍就不用+1了。
=========================
老师您一说,我明白了!老师就是老师!我改错如下:
[(N-1)÷16取整+1]×16,我明白了,计算机的计数跟生活中的计数不一样,计算机计数是从0开始的,而本题的N个字节是按10进制说的,从0开始数,0就是N里面的1,所以公式里面应该减1.

[  游客   发表于  2009-02-18 22:38  ]

第五题在masm6.0中通不过编译,在c segment 这一句出错了

[  游客   发表于  2009-05-23 13:33  ]

第5题要把mov bx,0放在循环外吧

 
 请输入验证码  (提示:点击验证码输入框,以获取验证码