当前位置:文档之家› 汇编基本知识

汇编基本知识

为什么assume了DS以后,在代码里面还要再次movax,data;movds,ax呢?
这里的assume 语句是告诉编译器各个段是由哪个段寄存器指向的,这样编译器就可以根据所设定的条件在需要时加上段前缀指令;它并不生成对段寄存器进行设置的指令,这个是需要程序自己来做的。

所以,就有了assume 语句之后,代码里自己设置相应的段寄存器。

嗯楼上说的对。

汇编语言有三类指令:(1)汇编指令,如mov ax,0等,有对应的机器码;(2)伪指令,如assume,db等,由编译器执行,计算机并不执行,没有对应机器码;(3)其他符号,如+、-等,由编译器识别,没有对应机器码。

所以,assume只是给编译器一个信息,告诉编译器相关段寄存器和段的联系。

但是,计算机并不执行它,要想真正将段地址存放到相关段寄存器中,需要用汇编指令来完成。

汇编语言中data segment什么意思
下面是汇编的基本框架:
定义数据段就是数据存放的地方
DATA SEGMENT
.....
DATA ENDS
定义代码段当然就是要执行的程序代码了
CODE SEGMENT
START:
........
CODE ENDS
END START
汇编伪指令assume cs:code,ds:data,ss:stack的含义
王爽的汇编教程中,下面一段汇编源文件,大意是把0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h这8个数,通过入栈出栈的方法逆序排列回原来的内存位置。

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,0,0,0,0,0,0,0,0
stack ends
code segment
start: movax,stack
movss,ax
mov sp,20h
movax,data movds,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,4cooh
int 21h
code ends
end start
那么问题来了。

问题①:开头的伪指令assume cs:code,ds:data,ss:stack作用既然不是把cs、ds、ss三个指针指向三个段,那写它有什么用?
问题②:ds,ss指针都通过movax,datamovds,ax和movax,stackmovss,ax被手动指向的正确的代码段。

唯独cs指针没有标明指向,程序是如何把cs指针指向正确的代码段的。

最佳答案
问题①:
你的程序中,可以用十个八个段,比如段名D1,D2,D3,D4,D5,D6,……
8086/8088 CPU的设计,是任一时刻,只能通过4个段寄存器最多同时访问4个段。

那么问题来了:
某个段(比如D5段)与哪个段寄存器关联、用哪个段寄存器访问呢?
assume伪指令就是用来解决这个问题的。

你assume ES:D5 以后,就将程序中的D5段与ES段寄存器绑定了,汇编程序能知道,访问D5段中的变量,要用ES作为段寄存器。

问题②:
DOS操作系统的程序装入功能,是这样设计的:
装入exe文件时,根据exe文件头中的信息,将CS:IP指向装入后内存中程序的入口(第一条执行指令),也就是说,要在装入程序时设置CS, IP两个寄存器。

对于其它3个段寄存器,DOS装入功能的处理,是将它们指向DOS操作系统为管理程序内存而创建的程序段前缀PSP的段地址。

那么问题来了:
程序运行后,要访问程序中的某个段里的数据,怎么办呢?
答案当然就是需要你自己在程序中加入将段地址传送到段寄存器的指令啦。

最后提一下,assume是给汇编程序在汇编翻译源程序时用的,段寄存器(CS除外)要自己设置初值是DOS操作系统的功能要求你程序这么做的。

追问
"assume ES:D5 以后,就将程序中的D5段与ES段寄存器绑定了"
这个“绑定”的意思是:如果用其他段寄存器比如DS:[bx]访问D5段,程序就会报错吗?
追答
举个例子吧:
假设,在D5段中有一个变量x02,你程序中某处有一条指令mov ax, x02
若没有assume,汇编这条mov指令时,汇编程序会报错。

因为不知道用哪个段寄存器。

有assume,汇编结果是mov ax, es:[(x02的偏移地址)],因为你assume告诉了汇编程序这个段用的是es这个段寄存器
MOV AX,DATAS MOV DS,AX 这两句是什么意思?
mov ax, datas ;将伪段地址放入ax中,datas不是指令,而是伪指令,实际上是一个动态的内存地址,要想运行,必须先其地相放入到ds中,但是内存数不能放入段地址。

所以movds,ax ;就是将段地址装入段寄存器,最终达到了段地址装入段寄存器的目的!
在80X86中规定,内存数不可以直接装入段寄存器,所以才会有这样的一次中转!
datas不是指令字,而是伪指令,实际上你可以理解他为一个标签,将这个标签装入AX中,实际装入的就是数据段的首地址!
指令与伪指令的区别在在于,指令是属性指令集(属于CPU的),而伪指令则是属于编译软件的,扫描后由编译软件进行的操作。

DOS系统功能调用表(INT 21H)
汇编中INT 21H是什么意思?
INT 软件中断,21H是函数入口地址,实际上就是调用DOS的系统功能。

是DOS的中断调用
比如
MOV AH 4CH
INT 21H
是返回DOS系统的
通过给AH寄存器赋值4CH,然后调用INT 21H指令,计算机就会根据AH寄存器中的值执行相应的操作,其中4CH是返回DOS系统,还可给AH寄存器赋其他值。

汇编程序结尾为什么要先结束代码段code ends 最后才结束程序段end start
code ends是表示代码段定义结束,而end start表示这个程序段全部结束,程序段不但有代码段还有其他段,也许你看的那个程序刚好只有一个start标签,所以误以为END start 就是用来结束start的.其实并不是这样.一个程序中可以有很多个标签.有一个start,下面,或者上面还会有otherstart标签等等....标签是没有结束的.执行完这个标签继续往下执
行,END start标签只是告诉编译器,从程序从这里结束,并且开始标签是start.。

相关主题