. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->包含多个段的程序
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  实验5 编写、调试具有多个段的程序 刚做好 发出来让大家看看有没错误 谢谢  [待解决] 回复[ 9次 ]   点击[ 377次 ]  
jingyarufeng
[帖 主]   [ 发表时间:2011-11-22 14:53 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-10-05 19:31
这一章的内容较少,有些知识需要在实践中掌握。这个实验,即是实验,也是学习内容。必须完成这个实验,才能继续向下学习。 
(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 
stack ends  

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 

end start 

①CPU执行程序,程序返回前,data段中的数据为多少? 
②CPU执行程序,程序返回前,cs=13d5、ss=13d4、ds=13d3。 
③设程序加载后,code段的段地址为X,则data段的段地址为X-2,stack段的段地址为X-1。 

调试过程如下: 
-r 
AX=0000  BX=0000  CX=0042  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000 
DS=13C3  ES=13C3  SS=13D3  CS=13D5  IP=0000   NV UP EI PL NZ NA PO NC 
13D5:0000 B8D413        MOV     AX,13D4 
-g 13d5:001d 

AX=13D3  BX=0000  CX=0042  DX=0000  SP=0010  BP=0000  SI=0000  DI=0000 
DS=13D3  ES=13C3  SS=13D4  CS=13D5  IP=001D   NV UP EI PL NZ NA PO NC 
13D5:001D B8004C        MOV     AX,4C00 
-d 13d3:0000 
13D3:0000  23 01 56 04 89 07 BC 0A-EF 0D ED 0F BA 0C 87 09   #.V............. 
13D3:0010  00 00 00 00 00 00 00 00-00 00 1D 00 D5 13 DB 0D   ................ 
13D3:0020  B8 D4 13 8E D0 BC 10 00-B8 D3 13 8E D8 FF 36 00   ..............6. 
13D3:0030  00 FF 36 02 00 8F 06 02-00 8F 06 00 00 B8 00 4C   ..6............L 
13D3:0040  CD 21 00 00 00 00 00 00-00 00 00 00 00 00 00 00   .!.............. 
13D3:0050  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................ 
13D3:0060  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................ 
13D3:0070  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................ 
-r 
AX=13D3  BX=0000  CX=0042  DX=0000  SP=0010  BP=0000  SI=0000  DI=0000 
DS=13D3  ES=13C3  SS=13D4  CS=13D5  IP=001D   NV UP EI PL NZ NA PO NC 
13D5:001D B8004C        MOV     AX,4C00 


(2)将下面的程序编译连接,用Debug加载、跟踪,然后回答问题。 
assume cs:code,ds:data,ss:stack 

data segment 
    dw 0123h,0456h 
data ends 

stack segment 
     dw 0,0 
stack ends 

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 

end start 

①CPU执行程序,程序返回前,data段中的数据为多少? 
解: 
13D3:0000  23 01 56 04 00 00 00 00-00 00 00 00 00 00 00 00   #.V............. 

②CPU执行程序,程序返回前,cs=13d5、ss=13d4、ds=13d3。 
解: 
-g 001d 

AX=13D3  BX=0000  CX=0042  DX=0000  SP=0010  BP=0000  SI=0000  DI=0000 
DS=13D3  ES=13C3  SS=13D4  CS=13D5  IP=001D   NV UP EI PL NZ NA PO NC 
13D5:001D B8004C        MOV     AX,4C00 

③设程序加载后,code段的段地址为X,则data段的段地址为X-2,stack段的段地址为X-1。 

④对于如下定义的段: 
name segment 
 ... 
name ends 

如果段中的数据占N个字节,则程序加载后,该段实际占有的空间为((N-1)/16+1)*16  N>0 。 
解:代码中 data段和stack段中的数据各占4个字节 
观察调试过程发现 

AX=13D3  BX=0000  CX=0042  DX=0000  SP=0010  BP=0000  SI=0000  DI=0000 
DS=13D3  ES=13C3  SS=13D4  CS=13D5  IP=001D   NV UP EI PL NZ NA PO NC 
13D5:001D B8004C        MOV     AX,4C00 
相关寄存器的值如下: 
DS=13D3    SS=13D4  CS=13D5 
stack段在 data段之后 
用stack段的起始地址减去data段的起始地址 即为data段的实际占有空间 为 (13d4*16+0000)-(13d3*16+0000)=10H,stack段的计算方法一样,然后我们观察code段的实际地址 
-u 
13D5:0000 B8D413        MOV     AX,13D4 
13D5:0003 8ED0          MOV     SS,AX 
13D5:0005 BC1000        MOV     SP,0010 
13D5:0008 B8D313        MOV     AX,13D3 
13D5:000B 8ED8          MOV     DS,AX 
13D5:000D FF360000      PUSH    [0000] 
13D5:0011 FF360200      PUSH    [0002] 
13D5:0015 8F060200      POP     [0002] 
13D5:0019 8F060000      POP     [0000] 
13D5:001D B8004C        MOV     AX,4C00 
中间略 
-t 

AX=4C00  BX=0000  CX=0042  DX=0000  SP=0010  BP=0000  SI=0000  DI=0000 
DS=13D3  ES=13C3  SS=13D4  CS=13D5  IP=0020   NV UP EI PL NZ NA PO NC 
13D5:0020 CD21          INT     21 
可见code的起始地址为 13D5:0000 结束地址为 13D5:0020  
所以 code段的实际占有的空间为20H。 

1,当N<16时,占有16个字节  
2,当N/16余数为0时,占有N个字节  
3,当N/16商为A,余数不为0时,占有(N/16+1)*16个字节 

因为段机制,我们知道一个段最小为16字节,而且是16字节的整数倍,所以,N个字节占用的空间不一定就是N,只有在N为16的整数倍的时候才正好占用N个字节的空间,否则,就会占用(N/16 + 1)*16个字节,不足16整数倍的会填充到16的整数倍。  




调试程序过程如下: 
-r 
AX=0000  BX=0000  CX=0042  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000 
DS=13C3  ES=13C3  SS=13D3  CS=13D5  IP=0000   NV UP EI PL NZ NA PO NC 
13D5:0000 B8D413        MOV     AX,13D4 
-u 
13D5:0000 B8D413        MOV     AX,13D4 
13D5:0003 8ED0          MOV     SS,AX 
13D5:0005 BC1000        MOV     SP,0010 
13D5:0008 B8D313        MOV     AX,13D3 
13D5:000B 8ED8          MOV     DS,AX 
13D5:000D FF360000      PUSH    [0000] 
13D5:0011 FF360200      PUSH    [0002] 
13D5:0015 8F060200      POP     [0002] 
13D5:0019 8F060000      POP     [0000] 
13D5:001D B8004C        MOV     AX,4C00 
-g 001d 

AX=13D3  BX=0000  CX=0042  DX=0000  SP=0010  BP=0000  SI=0000  DI=0000 
DS=13D3  ES=13C3  SS=13D4  CS=13D5  IP=001D   NV UP EI PL NZ NA PO NC 
13D5:001D B8004C        MOV     AX,4C00 
-d 13d3:0000 
13D3:0000  23 01 56 04 00 00 00 00-00 00 00 00 00 00 00 00   #.V............. 
13D3:0010  00 00 00 00 00 00 00 00-00 00 1D 00 D5 13 DB 0D   ................ 
13D3:0020  B8 D4 13 8E D0 BC 10 00-B8 D3 13 8E D8 FF 36 00   ..............6. 
13D3:0030  00 FF 36 02 00 8F 06 02-00 8F 06 00 00 B8 00 4C   ..6............L 
13D3:0040  CD 21 00 00 00 00 00 00-00 00 00 00 00 00 00 00   .!.............. 
13D3:0050  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................ 
13D3:0060  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................ 
13D3:0070  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................ 
-t 

AX=4C00  BX=0000  CX=0042  DX=0000  SP=0010  BP=0000  SI=0000  DI=0000 
DS=13D3  ES=13C3  SS=13D4  CS=13D5  IP=0020   NV UP EI PL NZ NA PO NC 
13D5:0020 CD21          INT     21 
附:CX中的值 
 在程序加载的时候,计算CX的值是通过段地址和偏移地址的变动来求得的。  
(1)如果程序只有一个段或者是程序中的最后一个段,那么在计算过程中,不涉及段地址的改变,即段地址不变,变的只是偏移地址,所以计算出来偏移地址改变量就是cx的值。  
(2)如果是多个段,计算的应该过程是这样的:比如说,整个程序拥有N(N>1)个段,这时CX的值为:前N-1个段占的字节 + 第N个段(即最后一个段)占的字节。其中,第N个段的计算原理见(1);而前N-1个段的计算是按照段地址的变动求得的,与偏移地址没有什么关系,所以,前N-1个段得到的值必然是16的倍数。  
举一个具体的例子来说吧。  
assume cs:codesg  
stack segment    
    db 'asdf'    
stack ends    
data segment  
    db '12345678901234567890'  
data ends    
codesg segment         
start:     
    mov ax,0    
    mov bx,0    
    mov ax , bx  
    mov ax,4c00h    
    int 21h   
    codesg ends  
end start   
这段程序包含三个段,前两个段占的字节数是通过段地址的变化得到的,即(codesg的段地址-stack的段地址)*16,我们可以不通过debug来求这个值,可以计算出前两个段每个段占的字节数,stack段定义了4个字符,但是,由于不是最后一个段,所以stack段占的字节数按照段地址的增量变化来计算,不足16*1个字节,占16个字节,即10H;同理,data段定义了20个字符,占的字节数为16*2=32,即20H。至于codesg段,是最后一个段,计算的时候依据的是偏移地址的变化来计算,各条指令相加3+3+2+3+2 = DH。所以,最终改程序的CX=10H+20H+DH=3DH  
如果以上例子中的程序调整为以下形式:  
assume cs:codesg  
codesg segment         
start:     
    mov ax,0    
    mov bx,0    
    mov ax , bx  
    mov ax,4c00h    
    int 21h   
    codesg ends  
stack segment    
    db 'asdf'    
stack ends    
data segment  
    db '12345678901234567890'  
data ends    
end start   
那么第一个段codesg占字节数为10H,第二个段stack占字节数为10H,第三个段data段占字节数为14H,程序总的字节数为10H+10H+14H = 34H。  
为什么同一个程序在编译后得到的CX长度不一样,应该比较明显了。 

(3)将下面的程序编译连接,用Debug加载、跟踪,然后回答问题。 
①CPU执行程序,程序返回前,data段中的数据为多少? 
解: 
13D6:0000  23 01 56 04 00 00 00 00-00 00 00 00 00 00 00 00   #.V............. 

②CPU执行程序,程序返回前,cs=14d3、ss=13d7、ds=13d6。 

 ③设程序加载后,code段的段地址为X,则data段的段地址为X+2,stack段的段地址为X+3。 
调试过程如下: 
-r 
AX=0000  BX=0000  CX=0044  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000 
DS=13C3  ES=13C3  SS=13D3  CS=13D3  IP=0000   NV UP EI PL NZ NA PO NC 
13D3:0000 B8D713        MOV     AX,13D7 
-u 
13D3:0000 B8D713        MOV     AX,13D7 
13D3:0003 8ED0          MOV     SS,AX 
13D3:0005 BC1000        MOV     SP,0010 
13D3:0008 B8D613        MOV     AX,13D6 
13D3:000B 8ED8          MOV     DS,AX 
13D3:000D FF360000      PUSH    [0000] 
13D3:0011 FF360200      PUSH    [0002] 
13D3:0015 8F060200      POP     [0002] 
13D3:0019 8F060000      POP     [0000] 
13D3:001D B8004C        MOV     AX,4C00 
-g 001d 

AX=13D6  BX=0000  CX=0044  DX=0000  SP=0010  BP=0000  SI=0000  DI=0000 
DS=13D6  ES=13C3  SS=13D7  CS=13D3  IP=001D   NV UP EI PL NZ NA PO NC 
13D3:001D B8004C        MOV     AX,4C00 
-d 13d6:0000 
13D6:0000  23 01 56 04 00 00 00 00-00 00 00 00 00 00 00 00   #.V............. 
13D6:0010  00 00 00 00 00 00 00 00-00 00 1D 00 D3 13 DB 0D   ................ 
13D6:0020  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................ 
13D6:0030  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................ 
13D6:0040  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................ 
13D6:0050  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................ 
13D6:0060  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................ 
13D6:0070  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................ 


(4)如果将(1)(2)(3)题中的最后一条伪指令"end start” 改为 "end"(也就是说,不指明程序的入口),则哪个程序仍然可以正确执行?请说明原因。 
解:第3题可以正确执行,因为第3题代码段就在开始的位置,所以,你懂的~~~~~~~ 

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

a segment 

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

a end 

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: 
      ? 

code ends 

end start 

解: 
assume cs:code 

a segment 

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

a end 

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 ax,a 
      mov ds,ax 
      mov ax,b 
      mov es,ax 
      mov ax,c 
      mov ss,ax 

      mov bx,0 
      mov cx,8 

     s:mov al [bx] 
       mov ah [bx] 
       add al,ah 
       mov ss:[bx],al 
       inc bx 
       loop s 

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: 
       ? 

code ends 

end start 

解: 
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 
      mov ss,ax 
      mov sp,16 
       
      mov bx,0 
      mov cx,8 

     s:push [bx] 
       add bx,2 
       loop s 

code ends 

end start
tomato
[第1楼]   [ 回复时间:2011-11-22 19:30 ]   [引用]   [回复]   [ top ] 
荣誉值:405
信誉值:0
注册日期:2008-01-19 14:51
第五题的程序写的有问题。
jingyarufeng
[第2楼]   [ 回复时间:2011-11-24 10:17 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-10-05 19:31
回复:[第1楼]
------------------
能否指正呢? 谢谢
tomato
[第3楼]   [ 回复时间:2011-11-24 20:51 ]   [引用]   [回复]   [ top ] 
荣誉值:405
信誉值:0
注册日期:2008-01-19 14:51
结果是正确的,但是没有看清题意,不是同一个段的数据自加,而是,两个不同的段的数据相加。“将a段和b段中的数据依次相加,将结果存在c段中”。
jingyarufeng
[第4楼]   [ 回复时间:2011-11-24 21:15 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-10-05 19:31
回复:[第3楼]
------------------
谢谢提醒啊 写的时候一慌神 把段前缀给忘了
现改正如下:
assume cs:code  

a segment  

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

a end  

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 ax,a  
      mov ds,ax  
      mov ax,b  
      mov es,ax  
      mov ax,c  
      mov ss,ax  

      mov bx,0  
      mov cx,8  

     s:mov al,[bx]  
       mov ah,es:[bx]  
       add al,ah  
       mov ss:[bx],al  
       inc bx  
       loop s  

code ends  

end start
grc10010010
[第5楼]   [ 回复时间:2011-11-25 17:28 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:13
注册日期:2011-07-13 08:38
第(2)题有疑问,debug加载后cx中的值为42h,此值为程序的长度,该长度减去前面2个段(data和stack)的长度为20h后,剩下的22h应为code的有效长度,所以你说的code的长度为20h可能有误,因为ip=20h指出的是当前代码的位置,并没有把代码的全部长度指出,因此code段的长度应为30h。
grc10010010
[第6楼]   [ 回复时间:2011-11-25 17:33 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:13
注册日期:2011-07-13 08:38
用u命令查看对应的机器码也可以发现未到int 21h时就有20h字节了,加上int 21h肯定超过20h了:
-u
0B72:0000 B8710B        MOV     AX,0B71
0B72:0003 8ED0          MOV     SS,AX
0B72:0005 BC1000        MOV     SP,0010
0B72:0008 B8700B        MOV     AX,0B70
0B72:000B 8ED8          MOV     DS,AX
0B72:000D FF360000      PUSH    [0000]
0B72:0011 FF360200      PUSH    [0002]
0B72:0015 8F060200      POP     [0002]
0B72:0019 8F060000      POP     [0000]
0B72:001D B8004C        MOV     AX,4C00
grc10010010
[第7楼]   [ 回复时间:2011-11-26 09:59 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:13
注册日期:2011-07-13 08:38
楼主第3题的答案也似乎有误:
②CPU执行程序,程序返回前,cs=14d3(此处应该是13d3)、ss=13d7、ds=13d6。  

 ③设程序加载后,code段的段地址为X,则data段的段地址为X+2(此处应该是X+3),stack段的段地址为X+3(此处应该是X+4)。

在我的电脑上实验下来cs=0c97,ss=0c9b,ds=0c9a,所以ds=cs(0c97)+3=ds,ss=cs(0c97)+4=ss。

以上答案请指正。
jingyarufeng
[第8楼]   [ 回复时间:2011-11-27 18:18 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-10-05 19:31
回复:[第5楼]
------------------
http://www.asmedu.net/bbs/pasteinfo.jsp?part=1&level=book&kind=1007&qkSg=2&qID=5437&readSg=1看看这个帖子 这个帖子写的很好 嘿嘿
jingyarufeng
[第9楼]   [ 回复时间:2011-11-27 18:18 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-10-05 19:31
回复:[第7楼]
------------------
嗯  确实有误 谢谢提醒 手动打的 还就错了
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved