实验2 多个逻辑段的汇编源程序编写与调试

实验任务1_1

①    在debug中将执行到line17结束、line19之前,记录此时:寄存器(DS) = _076A___, 寄存器(SS) =_076B_, 寄存器(CS) = 076C

②   假设程序加载后,code段的段地址是X,则,data段的段地址是_X-2H_, stack的段地址是_X-1H_

由于data段、stack段刚好各分配了16B的单位,而系统为段内存分配都是以16B为单位分配的,由于物理地址 = 段地址 × 16 + 偏移地址,因此相隔16B正好段地址相差1H

 

实验任务1_2

1在debug中将执行到line17结束、line19之前,记录此时:寄存器(DS) = _076A___, 寄存器(SS) =_076B___, 寄存器(CS) = _076C___

2假设程序加载后,code段的段地址是X,则,data段的段地址是_X-2H_, stack的段地址是_X-1H_

由于data段、stack段刚好各分配了16B的单位,而系统为段内存分配都是以16B为单位分配的,由于物理地址 = 段地址 × 16 + 偏移地址,因此相隔16B正好段地址相差1H

 

实验任务1_3

1.在debug中将执行到line17结束、line19之前,记录此时:寄存器(DS) = _076A___, 寄存器(SS) =_076C___, 寄存器(CS) = _076E___

2.假设程序加载后,code段的段地址是X,则,data段的段地址是X-4H_, stack的段地址是X-2H_

 

 

实验任务1_4

1.在debug中将执行到line9结束、line11之前,记录此时:寄存器(DS) = _076C___, 寄存器(SS) =_076E___, 寄存器(CS) = _076A___

2 .假设程序加载后,code段的段地址是 X_,则,data段的段地址是_X+2H_, stack的段地址是X+4H_

 

 

实验任务1_5

 

基于上述四个实验任务的实践、观察,总结并回答:

 

1 对于如下定义的段,程序加载后,实际分配给该段的内存空间大小是 16Byte

 

xxx segment
db N dup(0)
xxx ends

 

2 如果将程序task1_1.asm, task1_2.asm, task1_3.asm, task1_4.asm中,伪指令 end start 改成end , 哪一个程序仍然可以正确执行?结合实践观察得到的结论,分析、说明原因。

 

Task1_4.asm任然可以正常运行

 

原因:end除了通知编译器程序结束外,还可以通知编译器程序的入口在什么地方。在程序6.2中我们用end指令指明了程序的入口在标号start处。

 

尾指令end 描述了程序的结束和程序的入口。在编译、连接后,"end start" 指明的程序入口,被转化为一个入口地址,存储在可执行文件的描述信息中。

 

实验任务二

编写一个汇编源程序,实现向内存单元b800:0f00 ~ b800:0f9f连续160字节,依次重复填充十六进制数

据03 04。

Tips:

1. 在实验1的实验任务3中,做过达到同样效果的实验。但当时是通过debug的f命令实现填充的。这一次,要求编程实现。

在debug中,使用f命令,向内存单元批量填写数据。

-f b800:0f00 0f9f 03 04   把内存单元区间b800:0f00 ~ b800:0f9f连续160个字节,依次重复填充十六进制数据03 04。

2. 编程实现时,注意进制问题、字节顺序问题。编写后,运行程序,如果与实验1的实验任务3结果不一致,说明程序编写有错误。

使用debug f命令把内存单元区间b800:0f00 ~ b800:0f9f连续160个字节,依次重复填充十六进制数据03 04结果如下

编程实现代码如下:

assume cs:code

code segment
start:
    mov ax, 0b800h
    mov ds, ax
    mov bx, 0f00h
    mov cx, 50h				
    mov ax, 0403h			
s:  mov ds:[bx], ax
    add bx, 2			
    loop s

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

通过编译连接运行编写的task2.asm,可以看到编程方式实现也达到了同样的效果。

 

实验任务三

已知8086汇编源程序task3.asm代码片段如下。

task3.asm

assume cs:code
data1 segment
  db 50, 48, 50, 50, 0, 48, 49, 0, 48, 49 ; ten numbers
data1 ends
data2 segment
  db 0, 0, 0, 0, 47, 0, 0, 47, 0, 0    ; ten numbers
data2 ends
data3 segment
  db 16 dup(0)
data3 ends
code segment
start:
 ; ×××
 mov ah, 4ch
 int 21h
code ends
end start

要求:

① 编程实现把逻辑段data1和逻辑段data2的数据依次相加,结果保存到逻辑段data3中。

② 在debug中加载、反汇编、调试。在数据项依次相加前,和相加后,分别查看三个逻辑段data1,

data2, data3对应的内存空间,确认逐一相加后,结果的确保存在了逻辑段data3中。

完整代码:

assume cs:code
data1 segment
db 50, 48, 50, 50, 0, 48, 49, 0, 48, 49 ; ten numbers
data1 ends
data2 segment
db 0, 0, 0, 0, 47, 0, 0, 47, 0, 0 ; ten numbers
data2 ends
data3 segment
db 16 dup(0)
data3 ends
code segment
start:
mov ax, data1
mov ds, ax
mov bx, 0
mov cx, 10
s:
mov ax, [bx]
add ax, [bx+16]
mov [bx+32], ax
inc bx
loop s

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

反汇编:

运行前后内存单元内容对比

可以看到实现了逻辑段data1和逻辑段data2的数据依次相加,结果保存到逻辑段data3中。

 

实验任务四

已知8086汇编源程序task4.asm代码片段如下。

task4.asm

assume cs:code
data1 segment
  dw 2, 0, 4, 9, 2, 0, 1, 9
data1 ends
data2 segment
  dw 8 dup(?)
data2 ends
code segment
start:
 
  ; ×××
  mov ah, 4ch
  int 21h
code ends
end start

要求:

1. 补全程序,实现把逻辑段data1中的8个字数据逆序存储到逻辑段b中。

完整代码:

assume cs:code

data1 segment
    dw 2, 0, 4, 9, 2, 0, 1, 9
data1 ends 

data2 segment
    dw 8 dup(?)
data2 ends

code segment
start:
    
    mov ax, data1
    mov ds, ax
    mov ax, data2
    mov es, ax
    mov ss, ax
    mov sp, 32

    mov bx, 0
    mov cx, 8
s1: push [bx]
    add bx, 2
    loop s1

    mov bx,16
    mov cx, 8
s2: pop  [bx]
    add bx, 2
    loop s2

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

2.汇编、连接后,在debug中加载程序,运行到line15程序退出前,使用d命令查看数据段data2对应的内存空间,确认是否实现题目要求。

可以看到运行前data2中为全0,运行后data2中为data1的逆序,成功实现。

 

实验任务五

使用任意文本编辑器,录入汇编源程序task5.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

阅读源程序,从理论上分析源代码的功能,尤其是line15-25,循环实现的功能是什么,逐行理解每条指令的功能。

对程序进行汇编、链接,得到可执行文件,运行并观察结果。

汇编链接运行观察实现结果,屏幕上显示出彩色的NUIST字样

使用debug工具对程序进行调试,执行到程序返回前,即line25执行之后、line27执行之前,观察结果

源代码中line19的作用是?

进行相与运算,结果-32,即把大写字母转化为小写字母

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

db 2,3,4,5,6
--> 改成:
db 5 dup(2) 

db 2,3,4,5,6
--> 改成:
db 5 dup(5)

基于观察,分析、猜测这里的数值作用是什么?

Line 4的内容的用途:8位色彩代码用来控制输出颜色。

 

实验任务六

已知8086汇编源程序task6.asm代码片段如下。

task6.asm

assume cs:code, ds:data
data segment
  db 'Pink Floyd   '  ; 16字节
  db 'JOAN Baez    ' ; 16字节
  db 'NEIL Young   ' ; 16字节
  db 'Joan Lennon   ' ; 16字节
data ends
code segment
start:
 ; ×××
 mov ah, 4ch
 int 21h
code ends
end start

要求:

 补全程序,将data段中的每行第一个单词从大写->小写。

完整代码:

assume cs:code, ds:data
data segment
db 'Pink Floyd      ' 
db 'JOAN Baez       ' 
db 'NEIL Young      ' 
db 'Joan Lennon     ' 
data ends
code segment
start:
mov ax, data
mov ds, ax
mov bx, 0
mov cx, 4
s: 
mov ax, [bx]
or ax, 20h
mov [bx], ax
add bx, 16
loop s

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

在debug中加载程序,反汇编,执行到line13退出前,用d命令查看data段对应的内存空间,确认每行第一个单词已经由大写->小写。

反汇编

成功实现data段对应的内存空间每行第一个单词由大写转化为小写。

 

实验任务七

问题场景描述:

Power idea公司1975年-1979年的基本情况如下:

程序task7.asm的逻辑段data中(line4-6),已经定义好了这些数据。

task7.asm

assume cs:code, ds:data, es:table
data segment
  db '1975', '1976', '1977', '1978', '1979'
  dw  16, 22, 382, 1356, 2390
  dw  3, 7, 9, 13, 28
data ends
table segment
  db 5 dup( 16 dup(' ') )  ;
table ends
code segment
start:
  mov ah, 4ch
  int 21h
code ends
end start

要求:

① 补全程序,实现题目要求,把年份、收入、雇员人数、人均收入,以结构化方式写入table段中。

完整代码:

assume cs:code, ds:data, es:table

data segment
    db '1975', '1976', '1977', '1978', '1979' 
    dw  16, 22, 382, 1356, 2390
    dw  3, 7, 9, 13, 28 
data ends

table segment
    db 5 dup( 16 dup(' ') )  ;
table ends

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

    mov bx, 0
    mov bp, 0
    mov cx, 5
years:
    mov ax, ds:[bx]
    mov es:[bp], ax
    mov ax, ds:[bx+2]
    mov es:[bp+2], ax
    add bx, 4
    add bp, 10h
loop years

    mov bp, 5
    mov cx, 5
income:
    mov ax, ds:[bx]
    mov es:[bp], ax
    add bx, 2
    add bp, 10h
loop income

    mov cx, 5
    mov bp, 10
people:
    mov ax, ds:[bx]
    mov es:[bp], ax
    add bx, 2
    add bp, 10h
loop people

    mov cx, 5
    mov bp, 5
average:
    mov ax, es:[bp]
    mov bl, es:[bp+5]
    div bl
    mov es:[bp+8], al
    add bp,10h
loop average

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

表格中,每行数据,在逻辑段table中占16个字节,各项数据占据字节大小分配如下。期中,数据之间用空格间隔。

② 汇编、连接后,在debug中加载、调试程序。灵活、合理使用u命令、g命令、d命令,显示刚开始逻辑段table的数据信息,以及,结构化存入数据后,数据段table的数据信息,确认实现题目要求。

 

 

 

 

所有数据都已完整、准确存入表中。

 

posted @ 2021-11-08 21:35  流年h  阅读(91)  评论(1编辑  收藏  举报