汇编语言王爽第四版 第六章内容解读(附实验五答案解析)

本文详细解析了汇编语言中关于数据、代码和栈在不同段的使用。通过实例展示了如何计算内存中数据的和,强调了数据、代码和栈在同一个段内的不便,提出使用不同段来存储它们的优势。并给出了实验代码,演示了如何在多个段中管理和转移数据。
摘要由CSDN通过智能技术生成

第六章内容解读 包含多个段的程序

汇编语言全部实验链接

6.1 在代码段中使用数据

问题:编程计算以下8个数据的和,并且将结果放置在ax寄存器中(通过循环的方式)

0123h 0456h 0789h 0abch 0defh 0fedh 0cbah 0987h

如果希望通过循环的方式进行累加,在累加之前需要将数据存储在连续的内存单元中,内存位置由操作为

我们自动分配

assume cs:code 
code segment
	dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
	
	mov bx,0
	mov ax,0
	mov cx,8
s: add ax,cx:[bx]				;将内存中的数据加到ax中
	add bx,2					;每次偏移地址移动两个单元
	loop s
	
	mov ax,4c00h
	int 21h
code ends

end

我们编译链接之后Debug看一下

在这里插入图片描述

u命令查看汇编指令之后,发现并不是我们书写的那些命令,用d命令查看程序内存(注意DS为0B2D,所以我们应该查看0B3D)

在这里插入图片描述

发现,内存中存储的竟然是我们引入的数据(一共16个字节),那么可能就是数据占了16字节,那么16字节之后应该是我们的汇编指令

了吧,再次用u指令查看一下

在这里插入图片描述

答案很明确了,我们的程序加载进入内存之后,占用内存空间16字节的数据(用dw定义的)占据了前16字节,之后才是汇编指令

那么应该如果让指令从我们的汇编指令开始呢?在源程序中用start标明一下

assume cs:code 
code segment
	dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
	start : mov bx,0
			mov ax,0
			mov cx,8
		s : add ax,cs:[bx]
        	add bx,2
        	loop s
        	
        	mov ax,4c00h
        	int 21h
code ends
end start 

start就表示了程序的开始的地址,CPU就从star指向的地址开始执行

6.2 在代码段中使用栈

解读程序6.3

在这里插入图片描述

首先定义了8个字型的数据(16B),然后定义了16字型的数据(32B)

因此CS:0~CS:0F存放前面的数据,CS:10到CS:2F作为栈空间,因此SP指针指向就是30H

剩下的就是将数据通过栈进行转移了

😃 😃 😃

检测点6.1

(1) mov cs:[bx],ax

(2)

分析:第一个dw一共有8个字型数据,占据了16字节(0~15)

第二个dw一共有10个字型的数据,占据了20个字节(16~35),因此栈空间的sp从36(十进制)开始

16进制的sp:24h

  1. cs
  2. 24h
  3. cs:[bx]
6.3 将数据、代码、栈放入不同的段

前面做法的弊端:将数据、代码、栈放入同一个段显得很冗杂并且边界的明确很麻烦、如果数据很长还有可能超出界限

因此我们考虑将他们分别存放到不同的段中

  • 我们将不同的数据放到不同的段中,在引用的时候,段的名称就代表了首地址,
  • 不同段的命名是为了让程序员理解,我们在设定具体的作用时还是要用汇编代码进行设置

实验五 编写、调试具有多个段的程序

千呼万唤始出来,终于开始实验五啦!

(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 

进入debug

在这里插入图片描述

首先查看DS=075A,因此我们查看076A:0 F的数据,确认是我们写入的数据

执行一下代码(g 001d)再次查看076A:0 F的内容,没有更改

(1)CPU执行程序,data数据段中的数据没有更改

(2)程序返回之前,cs=076C ss=076B ds=076A

(3)data段地址=X-2 stack段地址=X-1

2.编译链接debug程序

在这里插入图片描述

(1)data段中的数据不变

(2)cs=076C ss=076B ds=076A

(3)data段地址=X-2 stack段地址=X-1

(4)((N+15)/16)*16

3.编译链接debug回答问题

在这里插入图片描述

  1. data段的数据不变还是076D :0000 23 01 56 04
  2. cs=076A ss=076E ds=076D
  3. data段地址=X+3 stack段地址=X+4
4.如果将(1)、(2)、(3)题中的最后一条伪指令“end start”改为“end”(也就是说,不指明程序的入口),则哪个程序仍然可以正确执行?请说明原因。

3是可以的,程序从所分配的空间开始执行,只有第三个开始是代码段,前两个都是数据段开始

5.编写代码
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

    s: mov al,[bx]

       add al,es:[bx]	;a , b的值加到al中

       mov dx,c

       mov ds,dx   		;ds -> c

       mov [bx],al

       mov ax,a			;重新规定指向

       mov ds,ax   

       inc bx

       loop s

    mov ax,4c00h

    int 21h

code ends

end start

5.编写程序
assume cs:code
a segment
	dw 1,2,3,4,5,6,7,8
a ends
b segment
    dw 0,0,0,0,0,0,0,0
b ends
code segment

start : mov ax,a
		mov ds,ax	;ds -> a
        mov ax,b
        mov ss,ax	;ss ->b
        mov bx,0
        mov sp,16	;8个字型数据占据了0~15
        mov cx,8
     s :push [bx]
     	add bx,2
     	loop s
code ends
end start
  • 13
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值