包含多个段的程序

包含多个段的程序

在程序中,不仅仅包含代码,还有数据和栈,要是将他们写在一起,那么在编程过程中会显得十分混乱,并且由于8086模式的限制,一个段的容量不能超过64KB。所以我们可以通过定义多个段来解决以上问题。

数据段

在汇编程序中,会遇到 dw ,这个的含义是定义一个字型数据(define word)。在x86架构中,一个字通常表示16位的数据,也就是2个字节。因此,dw 伪指令用于在程序的数据段中为变量分配空间并赋初值。

假设有以下的汇编代码:

assume cs:code

code segment

;data
    dw 0000h,0001h,0002h,0003h,0010h

;program
    mov ax,0h
    mov bx,ax
    mov cx,ax
    mov dx,ax
         
         mov cx,5h
;looper
looper:  add ax,cs:[bx]
         add bx,21h
         loop looper

;quit program
    mov ax,4c00h
    int 21h

code ends

end

这里,我们定义了5个字型数据,他们所占用的内存空间大小为10个字节,并在 looper 中对这5个字节的数据进行累加,编译链接后,在 debug 中使用 u 查看指令,可以发现程序并不是如我们期待的那样子,这是因为对于前面所定义的数据,它也当做指令了。

无入口点

所以,为了解决这个问题,我们加入一个标识符用来说明程序开始执行的位置,这个标识符和代码最后一行的 end 相匹配,修改后的代码如下:

assume cs:code

code segment

;data
   dw 0000h,1111h,2222h,3333h,6666h

;program
__start: mov ax,0h
         mov bx,ax
         mov cx,ax
         mov dx,ax
         
         mov cx,5h
;looper
looper:  add ax,cs:[bx]
         add bx,21h
         loop looper

;quit program
   mov ax,4c00h
   int 21h

code ends


end __start

使用 __start 标识符,并且修改 end 为相匹配的 end __start,再次编译链接后,查看:

带有入口点

使用 end __start 来表明程序的入口点为 __start 段,这样,程序被加载到内存后,就会从指定的位置开始运行,用这种方法,我们就可以将程序的数据段和指令段分开来:

assume cs:code

code segment

    ;数据

__start:

    ;指令

code ends

end __start

在计算机汇编语言中,"栈"(Stack)是一种用于临时存储数据和管理程序执行的数据结构。它是一种后进先出(Last In, First Out,LIFO)的数据结构,意味着最后压入栈的数据将首先被弹出。

栈通常由硬件或者操作系统提供支持,以便程序可以使用它来进行临时存储。它由两个基本操作组成:

  1. 压栈(Push): 将数据放入栈的顶部。这意味着数据被添加到栈的末尾。

  2. 弹栈(Pop): 从栈的顶部移除数据。这会导致栈顶的数据被删除,同时栈的大小减小。

通常,栈用于存储局部变量、返回地址、函数参数等。当程序调用一个函数时,通常会将返回地址和函数参数压入栈中,然后在函数执行完毕后,再通过弹栈操作恢复之前的状态,包括返回地址,使程序可以继续执行。

汇编语言中提供了特定的指令来执行栈操作,如PUSH(压栈)和POP(弹栈)。这些指令可以直接操作硬件栈,以实现数据的保存和恢复。

总结来说,栈在计算机汇编中是一种用于存储临时数据和管理程序执行的数据结构,它遵循后进先出的原则,由压栈和弹栈操作来管理数据。

举个简单的例子:

assume cs:code

;define data segment
data segment

   dw 0000h,0001h,0002h,0003h,0005h,0006h

data ends

;define stack segment
stack segment
   
   dw 0,0,0,0,0,0

stack ends

;define code segment
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 ah,4ch
   int 21h

code ends

end __start

这里定义了多个段:数据段(data segmment)、栈(stack segmment)、代码段(code segmment),对于不同的段,只是他们的段名不一样而已。

访问 data 段的数据得通过地址来访问:

mov ax,data
mov ds,ax
mov cx,ds:[2]

code 段中,使用指令:

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

设置 ss 指向 stack ,设置 ss:sp 指向 stack:20 ,CPU执行这些指令时,将会把 stack 段当做栈空间来使用。

posted @ 2023-07-29 11:21  fkkt-55  阅读(28)  评论(0编辑  收藏  举报