实验3 多个段的汇编源程序编写与调试

实验任务1

源代码

assume cs:code, ds:data
data segment
db 'Nuist'
db 5 dup(2)
data ends

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

mov ax, 0b800H
mov es, ax

mov cx, 5
mov si, 0
mov di, 0f00h
s: mov al, [si]
and al, 0dfh
mov es:[di], al
mov al, [5+si]
mov es:[di+1], al
inc si
add di, 2
loop s

mov ah, 4ch
int 21h
code ends
end start

 

下图为运行结果&debug到程序返回前的截图

改变data段line4中的值后的结果

 

 

 由两段代码及结果分析得到data段line4的字节数据用途是显示line段字符串的颜色

实验任务2

task2.asm源代码

assume cs:code, ds:data
data segment
	db 23,50,66,71,35
data ends
code segment
start: 	
	mov ax, data
	mov ds, ax  ;设置内存段地址
	mov ax, 0
	mov si, 0
	mov bl, 10  ;每次除以10,所以除数只需要8位,存储在bl中
	mov cx, 5  ;需要做5次循环
	
s:	mov al, ds:[si]  
	div bl  ;除以10
	mov bh, ah  ;ah中存储余数,因为寄存器冲突使用bh存储余数
	mov dl, al  ;al中存储商
	add dl, 30h  ;转换成ASCII码值,先输出商的值
	mov ah, 2
	int 21h

	mov dl, bh  ;输出余数的值
	add dl, 30h
	mov ah, 2
	int 21h
	mov ax, 0
	inc si
	loop s  ;循环

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

运行结果截图

 

 

 实验任务3

源代码文件

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

  根据理论分析,程序并没有改变data段中的数据,所以(1)的答案为:

   23 01 56 04 89 07 bc 0a ef 0d ed 0f ba 0c 87 09

下图为反汇编查看data段中数据的截图,观察到的结果和理论分析一致

 下图为在debug中执行到程序返回前的调试截图,得到(2)的答案:cs = 076c  ss = 076b ds = 076a

 

 

 data段定义了8个字即16个字节的空间,stack段定义了16个字节的空间,所以data段与stack段相差10h个字节,stack段又与cs段相差10h个字节。

(3)的答案为:data段的段地址为X-2,stack段的段地址为X-1

实验任务4

源代码:

 

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)根据理论分析,程序没有改变data段的数据,所以data段中的数据应该与源代码中data段的数据一致,即 23 01 56 04

(2)下图为在debug中执行到程序返回前的调试截图,由此得到答案:cs = 076c ss = 076b ds = 076a

 

 (3)虽然data段只定义了4个字节的数据,但是根据段的定义,段的大小至少为16个字节,所以data段依然占用16个字节,stack段同理。所以data段的段地址为X-2,stack段的段地址为X-1

(4)因为一个段至少有16个字节,所以该段实际占有的空间为 [N/16]*16,其中N/16向上取整。

实验任务5

源代码

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

(1)data段的数据没有变化,数据为 01 23 56 04

(2)下图为debug中执行到程序返回前的调试截图,可以得到答案cs = 076a ss = 076e ds = 076d

 

 (3)分析源代码,可以知道data段和stack段定义在code段之后,code段占用的字节空间为cx,所以data段的段地址为X+[cx/16]+1,ss段的段地址为X+[cx/16]+2,其中cx/16向上取整。

实验任务6

 

 (3)题中的程序仍然可以正确执行。因为只有(3)的程序中的data段和stack段是定义在code段后面的,在反汇编成源代码时code段代码依然可以正确执行。另外两题的code段代码都定义在data和stack段后面,会将data和stack段的数据也反汇编成要执行的code代码,不能正确执行。

实验任务7

源代码

 

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

c1 segment   ; 在集成软件环境中,请将此处的段名称由c→改为c1或其它名称
  db 8 dup(0)
c1  ends

code segment
start:
    mov bx, 0
    mov cx, 8
s:
    mov si, a
    mov ds, si
    mov al, ds:[bx]  ;将a段中的数据存入al
    mov si, b
    mov ds, si
    add al, ds:[bx]  ;将a段与b段的数据相加
    mov si, c1
    mov ds, si
    mov ds:[bx], al  ;将结果存入c1段中
inc bx loop s mov ax, 4c00h
int 21h code ends end start

 

下图为逻辑段c1的数据的截图,验证程序正确实现了题目要求

 

 实验任务8

源代码

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 bx, 0
    mov cx, 8
s:    mov si, a
    mov ds, si
    push ds:[bx]  ;先将a段的数据压入栈中
    add bx, 2
    loop s
    mov bx, 0
s0:    mov si, b
    mov ds, si
    pop ds:[bx]  ;出栈存入b段内存
    add bx, 2
    loop s0

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

下图为逻辑段c的数据的截图,验证了所编写的程序正确实现了题目要求

 

 

 

 实验结论

1. 通过本次实验更加明确了段的定义:一个段的大小至少为16个字节,段的起始地址应该为16的倍数,也就是说即使一段中定义的字节数不足16个字节也占用至少16个字节的空间。

2. 学会了div指令的用法:若除数为8位,被除数则为16位默认在ax中存放,al存储商,ah存储余数;若除数为16位,被除数则为32位在dx和ax中存放,ax存储商,dx存储余数;



 

posted @ 2020-11-22 21:42  candice12321  阅读(100)  评论(2)    收藏  举报