汇编语言(王爽)实验五

爱⌒轻易说出口 提交于 2020-02-29 16:44:03

实验五

1、将下面的程序编译、连接,用Debug加载、跟踪,然后回答问题

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段中的数据为多少? 不变

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

程序刚加载时,ds=075A,因为psp的存在,data段段地址为076A,赋值以后ds=076A,而data段占16个字节076A:10=076B:0,cs段同理,虽然在物理地址上这三个段是连续的,但由于被分为三个段,那么段地址必定要不同

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

2、将下面的程序编译、连接,用Debug加载、跟踪,然后回答问题

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

我们观察到data段和stack段都不足16个字节,而汇编中会自动分配16个字节的空间,不足的用0补全

CPU执行程序,程序返回前,data段中的数据为多少? 不变

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

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

总结:定义了一个名为xx的段后,其中数据占n个字节,则为其分配的空间是16的倍数并大于等于段中数据的字节数(n/16+1)*16(/为整数除法),假设xx中有17字节的数据,则会为其分配32个字节的空间

3、将下面的程序编译、连接,用Debug加载、跟踪,然后回答问题

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段中的数据为多少? 不变

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

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

用R命令发现cx的值为44H(程序长度),data段和stack段不足16个字节,补0,所以这两个段实际占20H个字节,所以cs段中可执行的字节数为(44H-20H=24H),不是10H的整数呗,所以补0(这些0并不算在程序长度中,至于为什么栈段和数据段补的0算在程序长度中,可能因为这些是程序执行时实际可用的数据和栈空间,而那些00机器码并不能执行),cs段一共占据30H个字节

程序长度=代码段中的代码长度+数据段长度+栈段长度(后两个都是16的整数倍)

4、如果将(1)、(2)、(3)题中的最后一条伪指令“end start”改为“end”(也就是说不指明程序的入口),则那个程序仍然可以正确执行?请说明原因。

都能运行,但3的程序可用正确执行

如果不指明程序的入口,那么从加载入内存的第一个单元开始执行,尽管前两题的代码是数据段放在最前,但也可以被翻译成汇编指令(毕竟最终都是机器码),但不是我们真正想要执行的,而第三题恰好程序段放在最先,CPU在执行真正的机器码时,遇到中断指令后返回,所以如果程序段不在最前,必须指定程序入口

5、编写code段中的代码,将a段和b段数据依次相加,结果存入c段

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 0,0,0,0,0,0,0,0
c ends

code segment

  start:   mov ax,a
           mov ds,ax           ;ds指向a段

           mov ax,b
           mov es,ax           ;es指向b段

           mov bx,0

           mov cx,8            ;计算8次
         s:mov dl, [bx]       ;将ds:[bx]内存单元按字节送入dl
           add dl, es:[bx]     ;将ds:[bx]与es:[bx]内存单元值相加

           push ds             ;保护ds值,因为下面用到ds了

           mov ax,c     
           mov ds,ax         ;将ds指向c段
           mov [bx],dl       ;将dl(a和b相对应内存单元内容之和)写入c中

           pop ds             ;将ds恢复

           inc bx             ;bx递增
           loop s

           mov ax,4c00h
           int 21h

code ends

end start

合理利用系统分配的栈来暂存ds的值

6、编写code段中的代码,用push指令将a段中前8个字型数据逆序存储到b段中

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 0,0,0,0,0,0,0,0
e ends

code sgement

	start: mov ax,a
    	   mov ds,ax
    	   
    	   mov ax,b	;将b段设置为栈段
    	   mov ss,ax
    	   mov sp,16
    	   
    	   mov bx,0
    	   
    	   mov cx,8
    	   
    	 s:push ds:[bx]
    	   add bx,2
    	   loop s
    	   
    	   mov ax,4c00h
    	   int 21h
    	   
 code ends
 end start

注意a段中的1、2、3、4、5其实都是字型数据,即0001H、0002H、0003H,而push、pop操作也恰好以字为单位

若为db 1,2,3,4,5,6,7,8,则均为字节型数据

参考

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!