美文网首页
[汇编语言] 实验5 编写、调试具有多个段的程序

[汇编语言] 实验5 编写、调试具有多个段的程序

作者: 耿杰 | 来源:发表于2019-07-14 21:17 被阅读0次

目录:

  • 一、将下面的程序编译、连接,用Debug加载、跟踪,然后回答问题
  • 二、将下面的程序编译、连接,用Debug加载、跟踪,然后回答问题
  • 三、将下面的程序编译、连接,用Debug加载、跟踪,然后回答问题
  • 四、如果将(1)、(2)、(3) 题中的最后一条伪指令end start改为end(也就是说,不指明程序的入口),则哪个程序仍然可以正确执行?说说明原因
  • 五、程序如下,编写code段中的代码,将a段和b段中的数据依次相加,将结果存在c段中
  • 六、程序如下,编写code段中的代码,用push指令将a段中的前8个字型数据,逆序存储到b段中

一、将下面的程序编译、连接,用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]      ; 把 0123h 放入栈顶
    push ds:[2]      ; 把 0456h 放入栈顶
    pop ds:[2]       ; 把 0456h 放入 ds:[2]的位置 
    pop ds:[0]       ; 把 0123h 放入 ds:[0]的位置 
    
    mov ax, 4c00h
    int 21h
       
code ends
end start
1、CPU 执行程序,程序返回前, data 段中的数据为多少?

0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h

  • 1、根据图1所示,栈段地址为076B,数据段地址为076A, 程序段地址为076C

  • 2、根据图1所示,程序刚进入的时候,076A:0000076A:0010的对应的内存空间的值,已经被赋值

    图1:程序刚进入
  • 3、根据图2所示,利用-g 001D,直接执行到076C:001D处,再次利用-d 076A: 0,检查数据段的数据,发现并没有变化 。

    图2,程序返回前
2、CPU 执行程序,程序返回前,cs = __、ss = __、ds = __

cs = 076C、ss = 076B、ds = 076A

  • 1、根据以上图2所示
3、设程序加载后,code 段的段地址为 X, 则 data 段的段地址为 ___, stack 段的段地址为___

data = X - 1, stack = X - 2

  • 1、根据第一个问题的分析。根据图1所示,栈段地址为076B,数据段地址为076A, 程序段地址为076C

二、将下面的程序编译、连接,用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
1、CPU 执行程序,程序返回前, data 段中的数据为多少?

0123H,0456H

  • 1、根据图1所示,栈段地址为076B,数据段地址为076A, 程序段地址为076C
  • 2、根据图1所示,程序刚进入的时候,076A:0000076A:0010的对应的内存空间的值,已经被赋值
    图1:程序刚进入
  • 3、根据图2所示,利用-g 001D,直接执行到076C:001D处,再次利用-d 076A: 0,检查数据段的数据,发现并没有变化 。
    图2,程序返回前
2、CPU 执行程序,程序返回前,cs = __、ss = __、ds = __

cs = 076C、ss = 076B、ds = 076A

  • 1、根据以上图2所示
3、设程序加载后,code 段的段地址为 X, 则 data 段的段地址为 ___, stack 段的段地址为___

data = X - 1, stack = X - 2

  • 1、根据第一个问题的分析。根据图1所示,栈段地址为076B,数据段地址为076A, 程序段地址为076C
4、对于如下定段的段, 如果段中的数据占N个字节,则程序加载后,该段实际占有的空间为____

16个字节

name segment
...
name ends
  • 1、在8086CPU架构上,段是以paragraph(16-byte)对齐的。程序默认以16字节为边界对齐,所以不足16字节的部分数据也要填够16字节。

三、将下面的程序编译、连接,用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
1、CPU 执行程序,程序返回前, data 段中的数据为多少?

0123H,0456H

  • 1、根据图1所示,栈段地址为076E,数据段地址为076D, 程序段地址为076A

  • 2、根据图1所示,程序刚进入的时候,076D:0000076D:0010的对应的内存空间的值,已经被赋值

    图1:程序刚进入
  • 3、根据图2所示,利用-g 001D,直接执行到076C:001D处,再次利用-d 076A: 0,检查数据段的数据,发现并没有变化 。

    图2,程序返回前
2、CPU 执行程序,程序返回前,cs = __、ss = __、ds = __

cs = 076A、ss = 076E、ds = 076D

  • 1、根据以上图2所示
3、设程序加载后,code 段的段地址为 X, 则 data 段的段地址为 ___, stack 段的段地址为___

data = X + 3, stack = X + 4

  • 1、根据第一个问题的分析。根据图1所示,栈段地址为076E,数据段地址为076D, 程序段地址为076A
image.png

五、如果将(1)、(2)、(3) 题中的最后一条伪指令end start改为end(也就是说,不指明程序的入口),则哪个程序仍然可以正确执行?说说明原因

(3)题可以正确执行。

分析:(2)题:

assume cs:code, ds:data,ss:stack
        
    
   
data segment
    dw 0123H, 0456H
data ends          

stack segment
    dw 1234, 5678
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
  • 1、根据图1所示,可以发现(2)题的第一条不是mov ax, stack。那么真正的程序入口在哪呢?

    图1
  • 2、(2)题的数据段,是4个字节;它的栈段是4个字节。根据内存对齐规则,数据段和栈段分别占用16个字节。那么就是就是32个字节。根据图1,可以看出程序的入口是076A,那么代码段的地址就是076C,也就是真正意义上程序的入口。可以查看图1,-u: 076C:0000的汇编代码。但是CPU执行了前面的无意义的汇编指令。

  • 3、只有(3)题能够正确的运行。程序的入口是正确的,并且只会执行,程序返回处,不会继续往下执行了。


五、程序如下,编写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   ; db 表示1个字节
c ends  
        
code segment 
start:  

    mov bx, 0
    mov cx, 8     ; 设置loop的循环次数
    
    s: mov ax, a  ; 取出 a 段的数据,并赋值给 dl
       mov ds, ax
       mov dl, [bx]
       
       mov ax, b  ; 取出 b 段的数据,对应的加给 dl
       mov ds, ax
       add dl, [bx]
       
       mov ax, c  ; 设置 c 段对应的内存单元的值
       mov ds, ax
       mov ds:[bx], dl
       
       inc bx
       loop s
    
    mov ax, 4c00h
    int 21h

code ends     
 
end  start

重点

  • 1、保存是1字节数据,而寄存器是2个字节的数据。注意存取。如果按照图1的代码,对dx进行操作,可以发现dx的值已经是0201,是读取的2个字节。为了避免这个问题,我们需要使用dl,来进行操作。
    图1

六、程序如下,编写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 cx, 8

mov ax, b
mov ss, ax
mov sp, 10h

s: push [bx]
inc bx
inc bx
loop s

mov ax, 4c00h
int 21h

code ends
end  start

结果

image.png

重点

  • 1、注意是dw
  • 2、前8个字节数据,其实是1、2、3、4、5、6、7、8

相关文章

网友评论

      本文标题:[汇编语言] 实验5 编写、调试具有多个段的程序

      本文链接:https://www.haomeiwen.com/subject/lbfikctx.html