汇编学习--第五天

第6章 包含多个段的程序

程序取得所需空间有两种方式:

1.加载程序的时候为程序分配

2.程序在执行过程中向系统申请

6.1 在代码段中使用数据

**

mov ax,[0]     ;debug中,会将ds:0一个字的数据(高位和低位)传入ax 16位寄存器

mov al,[0]    ;debug中,会将ds:0中的一个字节数据传入al 8位寄存器
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

"dw"--"define word"定义字型数据

当我们使用u指令查看程序时

前面一堆我们不知道的代码,这是在程序中的代码段,这个代码段在这里是由dw定义,8个字型数据,16个字节,所以我们的汇编代码应该在cs:10处

在我们debug中执行程序时,需要将IP调整为10

在上面程序中,我们在第一条汇编指令前面加上一个标号start。

这个start在end后面出现,因此我们使用end指明程序的入口地址。你可以这样理解:前面的start标号仅仅就是个标记,你第一次看到不能说明说明,只有你在看到下面end start时,你才知道start是程序的入口。

在程序生成时就会自动设置程序的入口地址

6.2 在代码段中使用栈

完成下面的程序,利用栈,将程序中定义的数据逆序存放

assume cs:code
code segment
    dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
    dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    
    start:    mov ax,cs
            mov ss,ax
            mov sp,30h

            mov bx,0
            mov cx,8
    s:        push cs:[bx]
            add bx,2
            loop s
            
            mov bx,0
            mov cx,8
    s0:        pop cs:[bx]
            add bx,2
            loop s0
            
            mov ax,4c00h
            int 21h
            
    code ends
    end start

逆序结果

在这段中定义了一个栈空间储存数据 cs:010h~cs:02fh,16个字,32字节大小

检测点 6.1

(1)

mov cs:[bx],ax

(2)

栈在程序中,所以段地址和当前地址相同,第一个空填 cs

从cs:10h开始往后20个字节,也就是cs:9h+20h=cs:29h,栈空间就是cs:10h~cs:29h

所以在入栈之前,SP=30h(第一次入栈时,栈顶在cs:28h)

第三个空 pop cs:[bx]

 6.3 将数据,代码,栈放入不同的段

实验 5 编写,调试具有多个段的程序

(1)

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

汇编程序多个段,相当于独立的,也就是地址都是0开始

因为在调试代码开始前,只有CS地址是已知的,data和stack还不知道,数据段的数据要查看到的话

1.将代码运行代码执行到mov ds,ax

2.因为这三个段空间是紧密排列,先数据段,再栈段,最后代码段(顺序与代码中的顺序有关),栈段占16字节,数据段占16字节,代码段开始在076c:0h,所以栈段开始在076b:0h,数据段开始在076a:0h

1)

23 01 56 04 89 07 BC 0A-EF 0D ED 0F BA 0C 89 09

2)

cs=076ch

ss=076bh

ds=076ah

3)

X-2H

X-1H

(2)

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)

2)

3)

X-2H

X-1H

4)

(N / 16 + 1) * 16

N / 16 不进行四舍五入的取整,这个公式实际上想说明,不满16字节,也占了16字节,也就是一行

(3)

1)

2)

3)

X+0003H

X+0004H

(4)

(3)能够正常正确执行,因为(1)(2)在程序中栈段和数据段都在代码段的前面,程序的地址不是代码段的地址

猜你喜欢

转载自www.cnblogs.com/Mayfly-nymph/p/11070795.html