鱼C论坛

 找回密码
 立即注册

不同的答案 实验5

热度 1已有 482 次阅读2011-10-27 13:02

(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 
    
a.CPU执行程序,程序返回前,data段的内容是多少? 
    无需debug调试, push ds:[0],push ds:[2]后,[2]在栈顶,经过 
pop ds:[2],pop ds:[0],栈顶先出栈,所以程序数据段依然没有变化。所以程序返回前,data中的数据为: 
0123H,0456H,0789H,0abcH,0defH,0fedH,0cbaH,0987H 

b.CPU执行程序,程序返回前,cs=____,ss=______,ds=______ 
    尽管可以用code,stack,data之类的标号来赋值,如cs=code,ss=stack,ds=data。不过,不同机器加载程序后,-t测试完后,会有具体的cs,ss和ds数值。我这边测试结果为cs=13F8,ss=13F7,ds=13F6 

c.设程序加载后,code段的段地址为X,则data段的段地址为___,stack段的段地址为___。 
  根据第二小问得出的计算结果为,data=X-2,stack=X-1。但如果根据下面的理解得到结果,或许更好,即: 
C:\masm>debug p61.exe 
-r 
AX=0000  BX=0000  CX=0042  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000 
DS=13E6  ES=13E6  SS=13F6  CS=13F8  IP=0000   NV UP EI PL NZ NA PO NC 
13F8:0000 B8F713        MOV     AX,13F7 
-d 13e6:100 
13E6:0100  23 01 56 04 89 07 BC 0A-EF 0D ED 0F BA 0C 87 09   #.V............. 
13E6:0110  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................ 
13E6:0120  B8 F7 13 8E D0 BC 10 00-B8 F6 13 8E D8 FF 36 00   ..............6. 
13E6:0130  00 FF 36 02 00 8F 06 02-00 8F 06 00 00 B8 00 4C   ..6............L 
13E6:0140  CD 21 00 00 00 00 F9 13-FB 0D 22 00 E6 13 02 32   .!........"....2 
13E6:0150  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................ 
13E6:0160  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................ 
13E6:0170  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................ 
-u 
13F8:0000 B8F713        MOV     AX,13F7 
13F8:0003 8ED0          MOV     SS,AX 
13F8:0005 BC1000        MOV     SP,0010 
13F8:0008 B8F613        MOV     AX,13F6 
13F8:000B 8ED8          MOV     DS,AX 
13F8:000D FF360000      PUSH    [0000] 
13F8:0011 FF360200      PUSH    [0002] 
13F8:0015 8F060200      POP     [0002] 
13F8:0019 8F060000      POP     [0000] 
13F8:001D B8004C        MOV     AX,4C00 
-u 
13F8:0020 CD21          INT     21 
13F8:0022 0000          ADD     [BX+SI],AL 
13F8:0024 0000          ADD     [BX+SI],AL 
13F8:0026 F9            STC 
13F8:0027 13FB          ADC     DI,BX 
13F8:0029 0D2200        OR      AX,0022 
13F8:002C E613          OUT     13,AL 
13F8:002E 0232          ADD     DH,[BP+SI] 
13F8:0030 0000          ADD     [BX+SI],AL 
13F8:0032 0000          ADD     [BX+SI],AL 
13F8:0034 0000          ADD     [BX+SI],AL 
13F8:0036 0000          ADD     [BX+SI],AL 
13F8:0038 0000          ADD     [BX+SI],AL 
13F8:003A 0000          ADD     [BX+SI],AL 
13F8:003C 0000          ADD     [BX+SI],AL 
13F8:003E 0000          ADD     [BX+SI],AL 
可知data段占据第一排(根据-d显示结果的方式,即每16个存储单元显示为一排),而data段共8个字型数据,故刚好占据一排空间,接下来就是stack段,也刚好占据一排,根据-u的结果可知,stack段下面一排存放的就是code代码段。因此可知,data段初始地址比code段小2排(即32个内存单元),stack的比code的小1排(即16个内存单元)。所以, 
code*16+0-(data*16+0)=2*16,而code=X,所以,data=X-2,同理,stack=X-1。 

(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 

a.CPU执行程序,程序返回前,data段的内容是多少? 
跟前面一样,data段的内容不便,依然为: 0123H,0456H 

b.CPU执行程序,程序返回前,cs=____,ss=______,ds=______ 
还是可以用cs=code,ss=stack,ds=data表示。具体执行时,不同的机器得出额结果不一样,我的机器给出的是,cs=13F8,ss=13F7,ds=13F6 

c.设程序加载后,code段的段地址为X,则data段的段地址为___,stack段的段地址为___。 
根据上面额结果,可知data=X-2,stack=X-1。 
也可以先用Debug加载p62.exe,再用-d和-u指令计算data和stack段的段地址,如题1一样。只不过,这里的data和stack段的数据所占空间为4个内存单元,不足一排,但仍要占据一排。所以结果跟题1一样。 

d.对于如下定义的段: 
  name segment 
  ... 
  name ends 
如果段中的数据占N个字节,则程序加载后,该段实际占有的空间为__。 
    段中的数据占N个字节,意味着占N个存储单元,在debug调试中输入-t后,显示以16个存储单元为一排。因此,用N/16表示占有几排,如果商为零,表示不足一排,仍给它一排的空间,也可写成(N/16+1)*16,如题2中 
data segment 
     dw 0123H,0456H 
data ends 
stack segment 
     dw 0,0 
stack ends; 
此外,题3中也是这样的。 

如果商刚好为整数t,表明则就占据t排空间,则实际占有空间为(N/16)*16,如题1中, 
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; 
若商为t,还带有余数,表明t排空间不够,t+1排又填不满,不过仍让填不满空间的一排占有一排,所以为t+1排,则实际占有空间为(N/16+1)*16。其中(N/16)都只取商的整数部分,小数部分去掉。 
因此,看了参考答案后,就写做(N/16+1)*16,恐怕不对吧。按照这个等式,像下面的段按照N/16+1)*16计算,应该占有(16/16+1)*16=32个存储单元,可是16个存储单元足以填充这些数据。 
data segment 
     dw 0123H,0456H,0789H,0abcH,0defH,0fedH,0cbaH,0987H 
data ends 
   那么用实验来证明,在用masm和link得到题1中的可执行文件(我这边的文件为p61.exe)后,进入cmd后,切换到c:\masm目录中。结果如下。 
C:\masm>debug p61.exe 
-r 
AX=0000  BX=0000  CX=0042  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000 
DS=13E6  ES=13E6  SS=13F6  CS=13F8  IP=0000   NV UP EI PL NZ NA PO NC 
13F8:0000 B8F713        MOV     AX,13F7 
-d 13e6:100 
13E6:0100  23 01 56 04 89 07 BC 0A-EF 0D ED 0F BA 0C 87 09   #.V............. 
13E6:0110  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................ 
13E6:0120  B8 F7 13 8E D0 BC 10 00-B8 F6 13 8E D8 FF 36 00   ..............6. 
13E6:0130  00 FF 36 02 00 8F 06 02-00 8F 06 00 00 B8 00 4C   ..6............L 
13E6:0140  CD 21 00 00 00 00 00 00-00 00 00 00 00 00 00 00   .!.............. 
13E6:0150  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................ 
13E6:0160  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................ 
13E6:0170  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................ 
其中第一排结果是data段占据的实际空间为,16个存储单元,此外,stack段也是如此,只占16个存储单元。 

(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 

a.CPU执行程序,程序返回前,data段的内容是多少? 
与前面一样,依然为0123H,0456H。 

b.CPU执行程序,程序返回前,cs=____,ss=______,ds=______ 
还是可以用cs=code,ss=stack,ds=data表示。具体执行时,不同的机器得出额结果不一样,我的机器给出的是,cs=13F6,ss=13FA,ds=13F9 

c.设程序加载后,code段的段地址为X,则data段的段地址为___,stack段的段地址为___。 
C:\masm>debug p63.exe 
-r 
AX=0000  BX=0000  CX=0044  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000 
DS=13E6  ES=13E6  SS=13F6  CS=13F6  IP=0000   NV UP EI PL NZ NA PO NC 
13F6:0000 B8FA13        MOV     AX,13FA 
-d 13E6:100 
13E6:0100  B8 FA 13 8E D0 BC 10 00-B8 F9 13 8E D8 FF 36 00   ..............6. 
13E6:0110  00 FF 36 02 00 8F 06 02-00 8F 06 00 00 B8 00 4C   ..6............L 
13E6:0120  CD 21 00 00 00 00 00 00-00 00 00 00 00 00 00 00   .!.............. 
13E6:0130  23 01 56 04 00 00 00 00-00 00 00 00 00 00 00 00   #.V............. 
13E6:0140  00 00 00 00 00 00 F9 13-FB 0D 22 00 E6 13 02 32   .........."....2 
13E6:0150  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................ 
13E6:0160  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................ 
13E6:0170  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................ 
-u  
13F6:0000 B8FA13        MOV     AX,13FA 
13F6:0003 8ED0          MOV     SS,AX 
13F6:0005 BC1000        MOV     SP,0010 
13F6:0008 B8F913        MOV     AX,13F9 
13F6:000B 8ED8          MOV     DS,AX 
13F6:000D FF360000      PUSH    [0000] 
13F6:0011 FF360200      PUSH    [0002] 
13F6:0015 8F060200      POP     [0002] 
13F6:0019 8F060000      POP     [0000] 
13F6:001D B8004C        MOV     AX,4C00 
-u 
13F6:0020 CD21          INT     21 
13F6:0022 0000          ADD     [BX+SI],AL 
13F6:0024 0000          ADD     [BX+SI],AL 
13F6:0026 0000          ADD     [BX+SI],AL 
13F6:0028 0000          ADD     [BX+SI],AL 
13F6:002A 0000          ADD     [BX+SI],AL 
13F6:002C 0000          ADD     [BX+SI],AL 
13F6:002E 0000          ADD     [BX+SI],AL 
13F6:0030 2301          AND     AX,[BX+DI] 
可知INT     21汇编指令对应的机器指令是位于13F6:0020的CD21。 
根据-d 13E6:100显示的结果可知,代码段code占据3排,而且3排没有排满,因为第三排中只有最前面两个内存单元被使用,为CD 21即该段程序的最后一条指令的机器码。尽管没有排满,但仍要占据一排。跟在code段后面的是data,然后才是stack段。所以data的初始地址比代码段的初始地址要大3排,即(16×data+0)-(16×X+0)=3×16,所以 
data=X+3。而data段只有2两个字型数据,占有4个内存单元,不足一排,根据公式,仍得占据一排,所以stack段的初始地址跟data段的相差一个一排,即16个内存单元。所以stack×16+0-data×16-0=16所以,stack=data+1=X+4。 


(4)如果将1、2、3题中的最后一条伪指令"end start"改为"end"(也就是说,不指明程序的入口),则哪个程序仍然可以正确执行?请说明原因。 
只有3题中可以正常运行。因为3题中,code段在最前面,cs:0直接指向code代码段,所以可以运行。而1和2题中,则是代码段放在最后,data段放在最前,所以cs:0指向data段,当然不会正确执行。 

(5)程序如下,编写code段中的代码,将a段和b段中的数据依次相加,将结果存到c段中。 
assume cs:code 
a segment 
  db 1,2,3,4,5,6,7,8 
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: 
    ? 
code ends 
end start 
首先根据题1、2和3中的理解,a、b和c段存放的都是8个字节型数据,占据8个内存空间,不足一排,但仍要占据一排,且根据段排列的先后顺序可知,b段的段地址要比a段的大16,c段的段地址要比a的大32。据此,编写如下。 
缺少的指令代码如下: 
mov ax,a 
mov ds,ax 
mov bx,0 
mov cx,8 
s:mov dl,[bx] 
  mov dh,0 
  mov al,[bx+16] 
  mov ah,0 
  add ax,dx 
  mov [bx+32],al 
  inc bx 
loop s 
mov ax,4c00H 
int 21H 

将上面的程序命名为p65.asm,经过编译连接后产生名为p65.exe的可执行文件。 
C:\masm>debug p65.exe 
-r 
AX=0000  BX=0000  CX=004D  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000 
DS=13E6  ES=13E6  SS=13F6  CS=13F9  IP=0000   NV UP EI PL NZ NA PO NC 
13F9:0000 B8F613        MOV     AX,13F6 

-d 13e6:100 
13E6:0100  01 02 03 04 05 06 07 08-00 00 00 00 00 00 00 00   ................ 
13E6:0110  01 02 03 04 05 06 07 08-00 00 00 00 00 00 00 00   ................ 
13E6:0120  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................ 
13E6:0130  B8 F6 13 8E D8 BB 00 00-B9 08 00 8A 17 8A 47 10   ..............G. 
13E6:0140  02 C2 88 47 20 43 E2 F3-B8 00 4C CD 21 C0 22 80   ...G C....L.!.". 
13E6:0150  3E 45 07 00 74 0A FF 36-56 07 E8 21 FC 83 C4 02   >E..t..6V..!.... 
13E6:0160  FF 06 56 07 5E 8B E5 5D-C3 90 55 8B EC 81 EC 90   ..V.^..]..U..... 
13E6:0170  00 56 C4 5E 06 26 8B 47-08 89 46 F8 26 83 7F 06   .V.^.&.G..F.&... 

-u 
13F9:0000 B8F613        MOV     AX,13F6 
13F9:0003 8ED8          MOV     DS,AX 
13F9:0005 BB0000        MOV     BX,0000 
13F9:0008 B90800        MOV     CX,0008 
13F9:000B 8A17          MOV     DL,[BX] 
13F9:000D 8A4710        MOV     AL,[BX+10] 
13F9:0010 02C2          ADD     AL,DL 
13F9:0012 884720        MOV     [BX+20],AL 
13F9:0015 43            INC     BX 
13F9:0016 E2F3          LOOP    000B 
13F9:0018 B8004C        MOV     AX,4C00 
13F9:001B CD21          INT     21 
13F9:001D C0            DB      C0 
13F9:001E 22803E45      AND     AL,[BX+SI+453E] 
-t 

AX=13F6  BX=0000  CX=004D  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000 
DS=13E6  ES=13E6  SS=13F6  CS=13F9  IP=0003   NV UP EI PL NZ NA PO NC 
13F9:0003 8ED8          MOV     DS,AX 
-g 0018 

AX=1310  BX=0008  CX=0000  DX=0008  SP=0000  BP=0000  SI=0000  DI=0000 
DS=13F6  ES=13E6  SS=13F6  CS=13F9  IP=0018   NV UP EI PL NZ NA PO NC 
13F9:0018 B8004C        MOV     AX,4C00 
-t 

AX=4C00  BX=0008  CX=0000  DX=0008  SP=0000  BP=0000  SI=0000  DI=0000 
DS=13F6  ES=13E6  SS=13F6  CS=13F9  IP=001B   NV UP EI PL NZ NA PO NC 
13F9:001B CD21          INT     21 
-g 

Program terminated normally 

-d 13e6:100 
13E6:0100  01 02 03 04 05 06 07 08-00 00 00 00 00 00 00 00   ................ 
13E6:0110  01 02 03 04 05 06 07 08-00 00 00 00 00 00 00 00   ................ 
13E6:0120  02 04 06 08 0A 0C 0E 10-00 00 00 00 00 00 00 00   ................ 
13E6:0130  B8 F6 13 8E D8 BB 00 00-B9 08 00 8A 17 8A 47 10   ..............G. 
13E6:0140  02 C2 88 47 20 43 E2 F3-B8 00 4C CD 21 C0 22 80   ...G C....L.!.". 
13E6:0150  3E 45 07 00 74 0A FF 36-56 07 E8 21 FC 83 C4 02   >E..t..6V..!.... 
13E6:0160  FF 06 56 07 5E 8B E5 5D-C3 90 55 8B EC 81 EC 90   ..V.^..]..U..... 
13E6:0170  00 56 C4 5E 06 26 8B 47-08 89 46 F8 26 83 7F 06   .V.^.&.G..F.&... 
发现,第三排为前两排数之和。说明该编程有效。好开心啊。呵呵。 

(6)程序如下,编写code段中的代码,用push指令将a段中word数据,逆序存储到b段中。 
assume cs:code 
a segment 
   dw 1,2,3,4,5,6,7,8 
a ends 

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

b ends 

code segment 
start: 
     ? 
code ends 

end start 
逆序排列,用入栈和出栈编程,再好不过的了。缺失的代码为 
mov ax,a 
mov ds,ax 
mov ss,b 
mov sp,20H 
mov bx,0 
mov cx,8 
s:push [bx] 
  inc bx 
  inc bx 
loop s 
mov ax,4c00H 
int 21H

路过

鸡蛋

鲜花

握手

雷人

全部作者的其他最新日志

发表评论 评论 (2 个评论)

回复 不说话 2012-10-22 19:47
第三行错了。
回复 小宝贝儿 2012-10-24 17:24
不说话: 第三行错了。
请问大侠,是哪道题啊?

facelist

您需要登录后才可以评论 登录 | 立即注册

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

GMT+8, 2024-5-3 20:13

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

返回顶部