汇编实验二

实验结论

1. 实验任务1

任务1-1

(1)task1_1.asm源码

assume ds:data, cs:code, ss:stack

data segment
db 16 dup(0)
data ends

stack segment
db 16 dup(0)
stack ends
code segment
start:
mov ax, data
mov ds, ax

mov ax, stack
mov ss, ax
mov sp, 16

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

(2)task1_1调试到line17结束、line19之前截图

 

(3)问题回答 ① 在debug中将执行到line17结束、line19之前,记录此时:寄存器(DS) = _076A___, 寄存器(SS) = __076B__, 寄存器(CS) = _076C___

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

                              (debug可得出:此题中CS=076C )

任务1-2

(1)task1_2.asm源码

assume ds:data, cs:code, ss:stack

data segment
    db 4 dup(0)
data ends

stack segment
    db 8 dup(0)
stack ends
code segment
start:
    mov ax, data
    mov ds, ax

    mov ax, stack
    mov ss, ax
    mov sp, 8

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

(2)task1_2调试到line17结束、line19之前观察寄存器DS, CS, SS值的截图

(3)问题回答 ① 在debug中将执行到line17结束、line19之前,记录此时:寄存器(DS) = _076A_, 寄存器(SS) = __076B__, 寄存器(CS) = _076C_

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

任务1-3

(1)任务task1_3.asm源码

assume ds:data, cs:code, ss:stack

data segment
    db 20 dup(0)
data ends

stack segment
    db 20 dup(0)
stack ends
code segment
start:
    mov ax, data
    mov ds, ax

    mov ax, stack
    mov ss, ax
    mov sp, 20

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

(2)task1_3调试到line17结束、line19之前观察寄存器DS, CS, SS值的截图

(3)问题回答 ① 在debug中将执行到line17结束、line19之前,记录此时:寄存器(DS) = _076A_, 寄存器(SS) = __076C__, 寄存器(CS) = _076E_

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

任务1-4

(1)任务task1_4.asm源码

 1 assume ds:data, cs:code, ss:stack
 2 code segment
 3 start:
 4     mov ax, data
 5     mov ds, ax
 6 
 7     mov ax, stack
 8     mov ss, ax
 9     mov sp, 20
10 
11     mov ah, 4ch
12     int 21h
13 code ends
14 
15 data segment
16     db 20 dup(0)
17 data ends
18 
19 stack segment
20     db 20 dup(0)
21 stack ends
22 end start

(2)task1_4调试到line9结束、line11之前,观察寄存器DS, CS, SS值的截图

(3)问题回答 ① 在debug中将执行到到line9结束、line11之前,记录此时:寄存器(DS) = _076C_, 寄存器(SS) = __076E__, 寄存器(CS) = _076A_

                        ② 假设程序加载后,code段的段地址是X,则,data段的段地址是_X+2_, stack的段地址是 _X+4_。

任务1-5

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

① 对于如下定义的段,程序加载后,实际分配给该段的内存空间大小是 __N个字节__。

xxx segment 

db N dup(0)

xxx ends 

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

    答:经过实践,伪指令 end start 改成 end后,只有task1_4.asm可以正确运行。因为end除了通知编译器程序结束外,还可以通知编译器程序的入口在哪,在本题的4个程序中,入口都在标号start处;去除start后,前三个程序无法找到入口,只有第四个程序的代码段在开头,可以找到入口。

 

2. 实验任务2

(1)汇编代码

 1 assume  cs: code
 2 
 3 code segment
 4 start:
 5     mov ax, 0b800h
 6     mov ds, ax
 7 
 8     mov bx, 0f00h
 9     mov cx, 50h
10     mov ax, 0403h
11 s : 
12     mov [bx], ax
13     add bx, 2
14     loop s
15 
16     mov ah, 4ch
17     int 21h
18 code ends
19 end start

(2)运行结果截图

(文件命名为1.ASM)

 与实验1的实验任务3结果一样

 

3. 实验任务3

(1)汇编代码

 1 assume cs:code ,ds:data1
 2 data1 segment
 3     db 50, 48, 50, 50, 0, 48, 49, 0, 48, 49 ; ten numbers
 4 data1 ends
 5 
 6 data2 segment
 7     db 0, 0, 0, 0, 47, 0, 0, 47, 0, 0       ; ten numbers
 8 data2 ends
 9 
10 data3 segment
11     db 16 dup(0)
12 data3 ends
13 
14 code segment
15 start:
16 mov ax, data1
17 mov ds, ax
18 mov bx, 0
19 mov cx, 0ah   ;循环10次
20 s:
21 mov ax, [bx]
22 add ax, [bx+10h]
23 mov [bx+20h], ax
24 inc bx
25 loop s
26 
27 mov ah, 4ch
28 int 21h
29 code ends
30 end start

(2)截图

-u查看加载,-g查看 运行结果

 相加之前的数据段:

可以看到虽然只有10个数据,但程序仍给data1,data2分配了16个字节空间,data3数据全为0

 相加之后的数据段:

可以看到data1和data2相加后到data3中

 

 4. 实验任务4

(1)代码

 1 assume cs:code
 2 
 3 data1 segment
 4     dw 2, 0, 4, 9, 2, 0, 1, 9
 5 data1 ends 
 6 
 7 data2 segment
 8     dw 8 dup(0)
 9 data2 ends
10 
11 code segment
12 start:
13     mov ax, data1
14     mov ds, ax
15     mov bx, 000eh
16      mov cx, 8h
17      mov si, 2h
18 s:
19     mov ax, [bx]
20     mov  [bx+si], ax
21     add si, 4
22     sub bx, 2
23     loop s
24     
25     mov ah, 4ch
26     int 21h
27 code ends
28 end start

(2)截图

-u查看加载,-g查看 运行结果

 初始内存:

 逆序存储后data2对应的内存空间:

 可以看到data2中存储的是data1的逆序,说明程序成功

 

5. 实验任务5

源代码:

 1 assume cs:code, ds:data
 2 data segment
 3         db 'Nuist'
 4         db 2, 3, 4, 5, 6
 5 data ends
 6 
 7 code segment
 8 start:
 9         mov ax, data
10         mov ds, ax
11 
12         mov ax, 0b800H
13         mov es, ax
14 
15         mov cx, 5
16         mov si, 0
17         mov di, 0f00h
18 s:      mov al, [si]
19         and al, 0dfh
20         mov es:[di], al
21         mov al, [5+si]
22         mov es:[di+1], al
23         inc si
24         add di, 2
25         loop s
26 
27         mov ah, 4ch
28         int 21h
29 code ends
30 end start

(1)line15-25,循环实现的功能是:

        将Nuist每个字母转换成大写并赋以相应的颜色

(2)运行结果截图:

(3)使用debug工具对程序进行调试,使用g命令一次性执行到程序返回前(即ine25执行之后、line27 执行之前)的截图:

 

 (4)源代码中line19的作用:

        小写变大写

(5)源代码中data段line4的字节数据的用途是?

       line4里5个字节单元的值改为db 5 dup(2)运行结果:

         line4里5个字节单元的值改为db 5 dup(5)运行结果:

      作用:设置NUIST的颜色

 

6. 实验任务6

(1)补全代码:

 1 assume cs:code, ds:data
 2 
 3 data segment
 4     db 'Pink Floyd      '
 5     db 'JOAN Baez       '
 6     db 'NEIL Young      '
 7     db 'Joan Lennon     '
 8 data ends
 9 
10 code segment
11 start:
12    mov ax, data
13    mov ds, ax
14    mov bx, 0
15    mov cx, 4           ;四个字符串
16    s0:
17     mov dx, cx
18    mov si, 0
19    mov cx, 4           ;四个字母
20    s:
21    mov al, [bx+si]
22    or al, 20h
23    mov [bx+si], al
24     inc si
25    loop s   
26 
27     mov cx, dx
28    add bx, 16
29     loop s0
30 
31    mov ah, 4ch
32    int 21h
33 code ends
34 end start

(2)在debug中加载、反汇编、调试截图:

 

(3)用d命令查看数据段data对应的内存空间的截图:

 单步调试到将data地址载入ds时:

在debug中运行到程序退出之前,使用d命令查看table段对应的内存空间的截图:

 可以看到,看数据段data每行第一个单词已经由大写->小写。

 

 7. 实验任务7

(1)编写代码:

 

 1 assume cs:code, ds:data, es:table
 2 
 3 data segment
 4     db '1975', '1976', '1977', '1978', '1979' 
 5     dw  16, 22, 382, 1356, 2390
 6     dw  3, 7, 9, 13, 28 
 7 data ends
 8 
 9 table segment
10     db 5 dup( 16 dup(' ') )  ;
11 table ends
12 
13 code segment
14 start:
15 
16     mov bp, 0                  ;table每行起始地址
17     mov si, 0                 ;每次+2
18     mov di, 0                  ;每次+4,年份起始
19     mov cx, 5
20     mov ax, data
21     mov ds, ax
22     mov ax, table
23      mov es, ax
24     
25 s:
26     mov ax, ds:[bp]                    ;年份
27     mov es:[di], ax
28     mov ax, ds:[bp+2]
29     mov es:[di+2], ax
30     mov ax, [si+014h]                   ;收入 si+014h
31     mov es:[di+5], ax
32     mov dx,[si+014h+2]
33     mov es:[di+7],dx
34     mov dx , [si+01eh]                   ;雇员  si +01eh
35     mov es:[di+0ah], dx
36 
37      mov dx, 0                                 ;人均收入
38     div word ptr [si+01eh]            ;dx*16+ax  /si+01eh
39     mov es:[bx+0dh], ax    
40      
41                                   ;分隔为空格
42     mov byte ptr es:[bx+4],020h    
43     mov byte ptr es:[bx+9],020h
44     mov byte ptr es:[bx+0ch],020h
45     mov byte ptr es:[bx+0fh],020h
46 
47    add di, 010h
48    add bp, 4
49    add si, 2
50    loop s
51 
52     mov ah, 4ch
53     int 21h
54 code ends
55 end start

 

(2)调试截图 :查看table段原始数据信息截图 在debug中运行到程序退出之前,使用d命令查看table段对应的内存空间的截图,确认信息是 否按要求结构化地写入到指定内存

debug 中可看到es段地址:076d

 

table段原始数据信息:

 

debug中运行到程序退出之前,使用d命令查看table段对应的内存空间:

 

 

实验结论

(1)十六进制数前面是字母的一定要加0;(编写中易出错!);

(2)在实验任务六中,一开始在s0中没有mov dx, cx(用dx暂存cx),在s中mov cx,dx (把外循环的cx还给它),陷入了死循环;

(3)编写时发现自己不太擅于用栈段相关操作,需加强。

 

posted @ 2021-11-07 21:35  tatazy  阅读(101)  评论(2)    收藏  举报