包含多个段(学习汇编)

将数据、代码、栈放入不同的段:把这些内容全部放在代码段中无疑会让程序显得混乱而且难以管理和操作,容易出错,所以,要把数据、代码和栈放入不同的段中,这也体现了软件工程中“分而治之”的思想。

assume cs:code, ds:data, ss:stack
data segment
dw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h

  //dw的意思是“define word”,即定义了已连串的字型数据(后面8个数据)
data ends

stack segmetn
dw 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
stack ends

code segment
start:
mov ax, stack
mov ss, ax
mov sp, 20h

mov ax, data
mov ds, ax

mov bx, 0
mov cx, 8
s:
push [bx]
add bx, 2
loop s

mov bx, 0
mov cx, 8
s0:
pop [bx]
add bx, 2
loop s0

mov ax, 4c00h
int 21h
code ends
end start

定义多个段的方法:定义数据段和栈段跟定义代码段一样,都是:XXX segment ; XXX ends;

对段地址的引用:如何访问到段的开始地址,寻址是按照:段地址×16 + 偏移地址来实现的。每一个段的标号就是表示段地址,比如:data segment;中data就是数据段的段地址。

  mov ax, data

  mov ds, data

就是使ds指向了data段中的第一个单元,那么以后:mov [0], ax; 就是把ax的内容送入到data段开始的第一个内存单元;但是,我们不能这样写:mov ds, data; data其实是一个段地址,一个值,这样写相当于把值直接送入ds,这是不允许的。

要注意,所谓的数据段,代码段,栈段都是我们自己定义的,是为了方便程序员阅读的,CPU并不知道哪些就是数据段,哪些是代码段,哪些是栈段。所以,data, code, stack只是一系列的标号而已,标号就是为了提高可读性。assume cs:code, ds:data, ss:stack;这句只是将你定义的具有一定用途的段和相关的寄存器联系起来,并不是说,CPU知道cs指向了code, ds指向了data,ss指向了stack;所以,我们仍然需要在程序中写:

  mov ax, stack

  mov ss, ax

  mov sp, 20h

这样类似的指令来指明ss指向了stack。所以,code, data, stack完全可以换成其他名字,只是我们在定义的时候需要定义一个可读性比较强的标号。

包含多个段(学习汇编)

时间: 2024-08-02 06:24:43

包含多个段(学习汇编)的相关文章

汇编入门学习笔记 (五)—— 包含多个段的程序

疯狂的暑假学习之  汇编入门学习笔记 (五)-- 包含多个段的程序 参考: <汇编语言> 王爽 第6章 1.在代码中使用数据. assume cs:code code segment dw 0123h,0456h,0789h,0defh mov ax,0 mov bx,0 mov ax,4c00H int 21h code ends end dw 表示定义字型数据,db 表示定义字节型数据. 上面代码编译连接,用debug调试,-u cs:0 查看汇编代码,发现没有看到 mov ax,0  m

小甲鱼零基础汇编语言学习笔记第六章之包含多个段的程序

在前面的几个章节中,我们的程序都是只有一个代码段,本章我们开始学习如何编写包含多个段的程序. 1.在代码段中使用数据 首先考虑这样一个问题,计算以下8个数据的和,结果存放在ax寄存器中: 0123H,0456H,0789H,0abcH,0defH,0fedH,0cbaH,0987H 在前面的课程中,我们都是累加某些内存单元中的数据,并不关心数据本身,可现在我们要累加就是已经给定了数值的数据. 代码如下: 1 assume cs:codesg 2 codesg segment 3 dw 0123H

栈Stack和段寄存器SS,SP(学习汇编)

1. 栈有2个基本操作:入栈.出栈 2. 栈顶的元素总是最后入栈,最先出栈:后进先出. 3. 8086CPU提供入栈和出栈的指令,最基本的两个是 PUSH(入栈) 和 POP(出栈) push ax 表示将AX寄存器的内容送入栈中, pop ax 表示从栈顶取出数据送入AX寄存器中.     8086CPU的入栈和出栈操作都是以字(word)为单位的. 4. 8086CPU中,段寄存器SS:存放栈顶段地址,段寄存器SP: 存放栈顶的偏移地址. 5. 任意时刻:SS:SP 指向栈顶元素. 6. 8

直接定址表(学习汇编)

1.我们可以使用一种标号,这种标号不但表示内存单元的地址,还表示了内存单元的长度,即表示在此标号处的单元,是一个字节单元,还是字单元,还是双字单元.如 a:db 1,2,3,4,5,6,7,8             改写为    a   db   1,2,3,4,5,6,7,8 b:dw  0                        改变为    b     dw   0 使用不带“:”的标号,它们是同时描述内存地址和单元长度的标号.这种标号包含了对单元长度的描述,所以,在指令中,它可以

int指令(学习汇编)

int指令 格式:int n n为中断类型码,它的功能是引发中断过程. CPU执行int n指令,相当于引发一个n号中断的中断过程,执行过程如下: 1)取中断类型码n: 2)标志寄存器入栈,IF=0,TF=0: 3)CS.IP入栈 4)(IP)=(n*4),(CS)=(n*4+2) 从此处转去执行n号中断的中断处理程序. 可以在程序中使用int指令调用任何一个中断的中断处理程序. assume cs:code code segment start:    mov ax,0b800h move s

内中断(学习汇编)

中断的意思是指,CPU不再接着(刚执行完的指令)向下执行,而是转去处理这个特殊信息. 注意,这里所说的中断信息,是为了便于理解而采用的一种逻辑上的说法.它是对几个具有先后顺序的硬件操作所产生的事件的统一描述. “中断信息”是要求CPU马上进行某种处理,并向所要进行的该种处理提供了必备的参数的通知信息. 中断信息可以来自CPU的内部和外部. 内中断的产生 对于8086CPU,当CPU内部有下面的情况发生的时候,将产生相应的中断信息: 1) 除法错误,比如:执行div指令产生的除法溢出: 2) 单步

转移指令的原理(学习汇编)

1.可以修改IP,或同时修改CS和IP的指令统称转移指令.有两种类型转移: (1)只修改IP是段内转移,如:jmp ax (2)修改CS和IP是段间转移,如:jmp 1000:0 2.操作符offset是一个伪指令,它的功能是取得标号的偏移地址. 3.jmp为无条件转移,可以只修改IP,也可以同时修改CS和IP的值,jmp指令要给出两个信息: (1)转移的目的地址. (2)转移的距离(段间转移,段内转移的短转移和近转移) 4.jmp short 标号(转到标号处执行) 这种指令实现的是段内短转移

使用BIOS进行键盘输入和磁盘读写(学习汇编)

1.键盘输入将引发9号中断,BIOS提供了int 9中断例程.CPU在9号中断发生后,执行int 9中断例程,从60h端口读出扫描码,并将其转化为相应的ASCII码或状态信息,存储在内存的指定空间(键盘缓冲区或状态字节)中.一般的键盘输入,在CPU执行完int 9中断例程后,都放到了键盘缓冲区中.键盘缓冲区有16个字单元,可以存储15个按键的扫描码和对应的ASCII码. 2.下面,我们通过下面几个键: A.B.C.D.E.shift_A.A 的输入过程,简要地看一下int 9中断例程对键盘输入的

汇编指令长度计算方法(学习汇编)

一.没有操作数的指令,指令长度为1字节.如es:ds:cbwxlat等. 二.操作数只涉及寄存器的指令,指令长度为2字节.如mov al,[si]mov ax,[bx+si]mov ds,ax等. 三.操作数涉及内存地址的指令,指令长度为3字节.如mov al,[bx+1]mov ax,[bx+si+3]lea di,[1234]mov [2345],ax等. 四.操作数涉及立即数的指令,指令长度为:寄存器类型+2.8位寄存器,寄存器类型=1:16位寄存器,寄存器类型=2.如mov al,8 ;