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

实验任务1

源代码文件task1.asm

assume cs:code, ds:data
data segment
    db 'Nuist'
    db 2,3,4,5,6
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

运行结果截图:

汇编、链接并运行task1.asm:

使用debug工具执行到程序返回前的结果:

修改line4里5个字节单元的值,重新汇编、链接、运行,观察结果:

基于观察,分析、猜测这里的data段line4数值作用是控制显示字符颜色的数值码。

 

实验任务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 cx, 5
    mov si, 0
    mov bl,10
    mov ax,0b900H
    mov es,ax
    mov di,0f00H
s:     mov al, [si]
    mov ah,0
    div bl
    add al,48
    add ah,48
    mov es:[di],al
    mov es:[di+1],ah    
    mov ah, 2
    mov dl, es:[di]
    int 21h
    mov ah, 2
    mov dl, es:[di+1]
    int 21h
    mov ah, 2
    mov dl, 32
    int 21h
    inc si
    add di,2
    loop s
    mov ah, 4ch
    int 21h
code ends
end start

运行结果截图:

 

实验任务3

源代码文件task3.asm:

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

汇编、链接并执行程序的截图:

(1)CPU执行程序,程序返回前,data段中的数据为如下所示

反汇编的结果:

执行到程序退出前,用d命令查看data段的数据:

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

执行到程序返回前的各个寄存器的数据:

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

单步调试查看各个段寄存器存储的数据:

 

实验任务4

源代码文件task4.asm:

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段中的数据为如下所示

反汇编,运行到程序返回前,用d命令查看data段中的数据:

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

执行到程序返回前各个段寄存器的数据:

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

单步调试查看各个段寄存器存储的数据:

(4)对于如下定义的段:

name segment

...

name ends

如果段中的数据占N个字节,则程序加载后,该段实际占有的空间为16字节。

 

实验任务5

源代码文件task5.asm:

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)CPU执行程序,程序返回前,data段中的数据为如下所示

反汇编,运行到程序返回前,用d命令查看data段中的数据:

(2)CPU执行程序,程序返回前,cs=076A、ss=076E、ds=076D

执行到程序返回前各个段寄存器的数据:

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

单步调试查看各个段寄存器存储的数据:

 

实验任务6

第(3)题的程序仍然可以正确执行,因为没有start指明程序的入口,程序将按照顺序执行,第(1)(2)题的程序数据段位于代码段的前面,所以数据段的数据会被当成指令被编译执行,虽然可能也会正确运行但会产生一些错误,但第(3)题数据段位于代码段的后面,按顺序执行不影响源程序的目的,并且会在代码段最后返回结果,不执行后面的数据段。

 

实验任务7

源代码文件task7.asm:

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

code segment
start:
    mov ax,a
    mov ds,ax
    
    mov ax,c
    mov es,ax
    mov cx,8
    mov di,0
s:    mov dl,ds:[di]
    mov es:[di],dl
    inc di
    loop s
    
    mov ax,b
    mov ds,ax
    mov cx,8
    mov di,0
s0:    mov dl,es:[di]
    add dl,ds:[di]
    mov es:[di],dl
    inc di
    loop s0
    mov ah,4ch
    int 21h

code ends
end start

汇编、链接并执行程序的截图:

使用debug查看当前寄存器的数据:

使用u反汇编:

使用g命令执行到程序返回前,并查看段c的数据:

 

实验任务8

源代码文件task8.asm:

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,b
    mov ss,ax
    mov sp,10H
    mov cx,8
    mov di,0
    mov ax,a
    mov ds,ax
s:    push ds:[di]
    add di,2
    loop s
    mov ah,4ch
    int 21h
       
code ends
end start

汇编、链接并执行程序的截图:

查看寄存器的数据并用u命令反汇编:

用g命令执行到程序返回前并查看段b的数据:

 

实验总结

(1)掌握了更多指令的使用方法和注意点。

(2)学会使用div命令和asc码与数值的关系及系统调用来将数字输出成字符。

(3)了解了系统在分配数据段中的存储地址时总是会分配16的倍数,方便CPU数位对齐处理。

(4)编写汇编程序时注意数字的进制,最好在16位进制后加上h,否则容易混淆。dosbox中出现的数据均为十六进制。

(5)使用分段的程序可以使数据和代码分离,同时需要在结束时指明程序的入口。

posted @ 2020-11-21 12:09  knight04  阅读(221)  评论(1)    收藏  举报
Live2D