第六章 包含多个段的程序
6.1 在代码段中使用数据
考虑计算以下8个数据的和 结果存入ax中。
0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
思考如果一个一个相加会很麻烦,考虑用循环:
CODES SEGMENT ASSUME CS:CODES dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h mov bx,0 mov ax,0 mov cx,8 s: add ax,cs:[bx] add bx,2 loop s MOV AH,4CH INT 21H CODES ENDS END dw(define word)用于定义字型数据,定义在此代码段的开始地址。怎么让cs:ip指向mov bx ,0呢?观察debug中cs:ip指向。
用伪指令start表示cpu从这里开始执行代码观察cs:ip指向
CODES SEGMENT ASSUME CS:CODES 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 AH,4CH INT 21H CODES ENDS END START6.2 在代码段中使用栈
程序:
assume cs:codesg
codesg 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 cx,8
s: push cs:[bx]
add bx,2
loop s
mov bx,0
mov cx,8
s1: pop cs:[bx]
add bx,2
loop s1
mov ax,4c00h
int 21h
codesg ends
end start
sp指向30h(48)是因为前16字节是指定的8个数据(0~15地址),后32个字节是16个字型数据的栈(16~47地址)ss:sp指向栈顶48地址
检测点6.1
(1): 添加代码:mov cs:[bx],ax
(2): cs、24h(0~15是给定的数据,16~35是栈段,栈指针在36也就是24h)、pop cs:[bx]
6.3 将数据、代码、栈放入不同的段
如果一个程序需要处理的数据很多上面的程序就不合适(一个段只能小于64kb)需要把数据,代码,栈分开
例如程序6.4:
DATAS SEGMENT dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h DATAS ENDSSTACKS SEGMENT dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 STACKS ENDS
CODES SEGMENT START: MOV AX,STACKS MOV ss,AX MOV SP,20H MOV AX, DATAS MOV DS,AX MOV BX,0 MOV CX,8 S: PUSH [BX] ADD BX,2 LOOP S MOV BX,0 MOV CX,8 S1: POP [BX] ADD BX,2 LOOP S1 MOV AH,4CH INT 21H CODES ENDS END START
实验5 编写、调试具有多个段的程序
(1)在调试的时候肝了一会儿,发现程序用debug打开后必须执行到 mov ds ,ax才能查看到数据段的数据;
1.
2.执行前:执行后:
3.data段地址:X-2 stack段地址:X-1
(2)
1.
2.cs=0770h ss=076fh ds=076eh
3.data段地址:x-2 stack段地址:x-1
(3)
1.
2.cs=076eh ss=0772h ds=0771h
3.data段地址:x-2 stack段地址:x-1
(4)只有3能正确执行,1和2不指明程序入口的话会把前面定义的数据段栈段当作指令执行,逻辑上是错误的。
(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 mov ax,c mov es,ax mov bx,0 mov cx,8 s: mov al,ds:[bx] add es:[bx],al inc bx loop smov ax,b mov ds,ax mov bx,0 mov cx,8
s1: mov al,ds:[bx] add es:[bx],al inc bx loop s1 mov ax,4c00h int 21h code ends end start
(6)
assume cs:code a segment db 1,2,3,4,5,6,7,8,9,0ah,0bh,0ch,0dh,0eh,0fh,0ffh a ends b segment db 0,0,0,0,0,0,0,0 b ends code segment start: mov ax,a mov ds,ax mov ax,b mov ss,ax mov sp,16 mov cx,8 mov bx,0 s: push ds:[bx] add bx,2 loop s mov ax,4c00h int 21h code ends end start