汇编实验5 编试、调试具有多个段的程序

实验任务

为便于排版及日后温习 ,附上所有代码

(1)源代码:

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段中的数据为多少?
0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h(未产生改变)

  • CPU执行程序,程序返回前,cs = 076C、ss = 076B、ds = 076A.(如下)

  

  • 设程序加载后,code段的的段地址为X,则data段的段地址为 X-2 ,stack段的短地址为 X-1 .(此问由上一题可得,code段的段地址即为cs,data段的段地址为ds,stack段的段地址为ss)

 

(2)源代码:

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段中的数据为多少?
0123h, 0456h
  • CPU执行程序,程序返回前,cs = 076C、ss = 076B、ds = 076A.
  • 设程序加载后,code段的的段地址为X,则data段的段地址为 X-2 ,stack段的段地址为 X-1 .

(前三问与第一个实验结果本质相同,故不作重复说明)

  • 对于如下定义的段:

  name segment

  ...

  name ends

  若段中的数据占N个字节,则程序加载后,该段实际占有的空间为(N / 16 + 1) * 16 字节.(现计算机内存最小单位为16字节,即所占空间必为16的整数倍)

 

(3)源代码:

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段中的数据为多少?
0123h, 0456h
  • CPU执行程序,程序返回前,cs = 076A、ss =076E、ds = 076D.

  • 设程序加载后,code段的的段地址为X,则data段的段地址为 X+3,stack段的段地址为 X+4.

 

(4)若将(1)(2)(3)中的最后一条伪指令“end start”改为“end”(即不指名程序入口),则哪个程序 仍可以正确执行?说明原因。

 书上了解到,伪指令end start是让程序从start处开始执行,若舍掉,即不指名程序入口,程序将默认从首个单元开始执行,三个程序的主要差别在于代码段的顺序不同,(1)和(2)开头的数据会被当做指令,故仅有(3)能够正确执行。

 

(5)

基本思路,分两次循环来完成,一次循环送值,一次循环相加

完整代码如下:

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   ; 在集成软件环境中,请将此处的段名称由c→改为c1或其它名称
    db 8 dup(0)
c ends        ; 改的时候要成对一起修改
code segment
start:
    mov ax,a
    mov ds,ax
    mov ax,c
    mov es,ax

    mov bx,0
    mov cx,8
s1: mov al,[bx]        
    mov es:[bx],al
    inc bx
    loop s1

    mov ax,b
    mov ds,ax
mov bx,0 mov cx,8 s2: mov al,[bx] add es:[bx],al inc bx loop s2 mov ax,4c00h int 21h code ends end start

相加之前es段中的值:

执行相加后:

完成!

此实验中有一点需注意,曾将指令

mov al,[bx]        
mov es:[bx],al

写作:mov es:[bx], [bx],结果汇编时报错。

遗忘知识点:给四个段寄存器ds,ss,es,cs复制必须要借由数据寄存器间接送值

 

(6)

上次遇到用栈没想出来,这次再试试看

完整代码如下:

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 8 dup(0)
b ends

code segment
start: 
    mov ax,a
    mov ds,ax  

    mov ax,b
    mov ss,ax
    mov sp,20h
    
    mov bx,0
    mov cx,10h
    
s:  push ds:[bx] 
    inc bx
    inc bx
    loop s

    mov ax,4c00h
    int 21h
code ends
end start

执行push指令之前:

执行之后:

完成!

中间有一个问题,就是ip的值,一开始填的是20h,结果发现将数据传进了ss:0010~ss:0020中,后来经同学提醒才得已改正。

posted @ 2018-11-28 21:58  鎖夢  阅读(264)  评论(3编辑  收藏  举报