汇编语言笔记06-包含多个段的程序

 

转载必须注明出处,违者必究。http://www.cnblogs.com/dennisOne

 

 

在操作系统的环境下,合法地通过操作系统取得的空间都是安全的。程序取得所需空间的方法有两种:一是在加载程序的时候为程序分配,再就程序在执行过程中向系统申请。

对于第一种方式,我们在程序中定义将要处理的数据,这些数据被编译、连接程序作为程序的一部分写入可执行文件中。当可执行文件的程序加载到内存中,这些数据也同时被加载到内存中。

   

在代码段中使用数据

例:计算以下8个数据的和,结果存在ax寄存器中:

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

 1 assume cs:code
 2 
 3 code segment
 4 
 5     dw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h
 6     
 7     start:  mov bx, 0
 8             mov ax, 0
 9     
10             mov cx, 8
11          s: add ax, cs:[bx]
12             add bx, 2
13             loop s
14     
15             mov ax, 4c00h
16             int 21h
17     
18 code ends
19 end start    ;通知编译器程序的入口,最终CS:IP指向该入口地址
debug分析:
c:\codes>debug p6_2.exe
-r
AX=0000  BX=0000  CX=0026  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=0BDA  ES=0BDA  SS=0BEA  CS=0BEA  IP=0010   NV UP EI PL NZ NA PO NC
0BEA:0010 BB0000        MOV     BX,0000
-u
0BEA:0010 BB0000        MOV     BX,0000
0BEA:0013 B80000        MOV     AX,0000
0BEA:0016 B90800        MOV     CX,0008
0BEA:0019 2E            CS:
0BEA:001A 0307          ADD     AX,[BX]
0BEA:001C 83C302        ADD     BX,+02
0BEA:001F E2F8          LOOP    0019
0BEA:0021 B8004C        MOV     AX,4C00
0BEA:0024 CD21          INT     21

DS=0BDA->CS=0BEA debug加载后,因为开头是数据(16bytes),end指定了start,所以将IP设置为10h,从而指向CS:IP的第一条指令。

   

在代码段中使用栈

例:使用栈将程序中定义的数据逆序存放。

 1 assume cs:code
 2 
 3 code segment
 4     
 5     dw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h
 6     dw 0, 0, 0, 0, 0, 0, 0, 0
 7        ; 用dw定义16个字型数据,在程序加载后,将取得16个字的内存空间,
 8        ; 存放这16个数据。程序中将这段空间当做栈使用。
 9     
10 start: mov ax, cs
11        mov ss, ax
12        mov sp, 20h     ; 设置栈顶ss:sp指向 cs:20
13         
14        mov bx, 0
15        mov cx, 8
16     s: push cs:[bx]
17        add bx, 2
18        loop s          ; 将0~15内存单元依次入栈
19         
20        mov bx, 0
21        mov cx, 8
22    s0: pop cs:[bx]
23        add bx, 2
24        loop s0         ; 出栈
25         
26        mov ax, 4c00h
27        int 21h
28         
29 code ends
30 end start

   

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

将数据、栈和代码放到一个段里面,显得非常混乱;其次,由于8086的段最大为64kb, 如果将数据、栈都放在代码中,挤占了代码段的空间。

例:使用栈将程序中定义的数据逆序存放。

 1 assume cs:code, ds:data, ss:stack
 2 
 3 data segment
 4     dw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h
 5 data ends
 6 
 7 stack segment
 8     dw 0, 0, 0, 0, 0, 0, 0, 0 
 9 stack ends
10 
11 code segment
12 start: mov ax, stack
13        mov ss, ax
14        mov sp, 10h        ; 设置栈顶ss:sp指向stack:10
15     
16        mov ax, data
17        mov ds, ax
18        mov bx, 0          ; 设置ds:bx指向数据段的第一个单元
19        
20        mov cx, 8
21     s: push [bx]
22        add bx, 2
23        loop s             ; 入栈
24 
25        mov bx, 0
26        mov cx, 8
27    s0: pop [bx]
28        add bx, 2
29        loop s0            ; 出栈
30        
31        mov ax, 4c00h
32        int 21h
33        
34 code ends
35 
36 end start

注意:

  • 伪指令"assumecs:code, ds:data, ss:stack"csdsss分别和codedatastack段相关联。但是伪指令是编译器执行的,cpu并不知道他们,所以并不会按照我们的意愿处理这些段。
  • 源程序中的"end start"说明了程序的入口,入口被写入可执行文件的描述信息,可执行文件中的程序被加载入内存中,CPUCS:IP被设置指向这个入口。

   

posted @ 2012-10-20 13:40  dennis_fan  阅读(534)  评论(0编辑  收藏  举报