CSDN博客

img sssa2000

汇编教程3-升级的准备

发表于2004/7/8 14:14:00  941人阅读

汇编教程3-升级的准备
  经过了前面2篇教程的学习,我向大家应该对汇编程序有了比较深刻的影响了吧?所以不能教扫盲帖了,可以升级了,不过,在升级前,不免的对一些基础的东西要了解一下。
一、 CPU的内部寄存器:
4个16位的通用寄存器:
_____________________________
|__ah________|____al_________|  ax   
|__bh________|____bl_________|  bx
|__ch________|____cl_________| cx 
|__dh________|____dl_________| dx
  
其中:一般来说,ax用作乘除法中的累加器,bx可存放地址,也可作指针寄存器。
cx可存放循环次数,dx可存放I/O号。
ah为两个4位,al为两个4位,所以,ax为16位,其余的以此类推


4个16位的指针寄存器
______________________________
|bp基址指针
|_____________________________
|sp堆栈指针   用于做堆栈顶端指针
|_____________________________
|si源变址寄存器  
|________________这两个有时用来做变址器,存放数据以及运算结果
|di目标寄存器
|_____________________________


4个16位的内部寄存器:

______________________________
|cs:代码段寄存器
|_____________________________
|ds:数据段寄存器
|_____________________________
|es:附加段寄存器
|_____________________________
|ss:堆栈段寄存器
|_____________________________

标志寄存器:

____________________________
            ip指令指针     |
___________________________|
   flagsh    |  flagsl     |
_____________|_____________|状态标志
16位的标志寄存器,只用了其中的9个标志位,6各状态标志位,3个控制标志位。

fh:
________________
   |of|df|if|tf|   
___|__|__|__|__|

fl:
___________________________
|sf|zf|空 |af|空 |pf|空|cf|
|__|__|_  |__|_  |__|__|__|

具体的每个标志位的意思我简单的讲一下,如果要编程还要自己看一下书
cf:进位标志,进位/借位的时候cf=1
pf:奇偶标志,当指令执行结果的低8位中含有偶数个1时,pf=1,f否则为0
af:辅助进位标志,加减法的结果的低字节向高4位有进/借位时af=1.
zf:0标志。运算结果为0时,zf=1
sf:符号标志,他和运算结果的最高位相同。负数为1,正数为1
of:溢出标志,补码运算有溢出时为1
上面是状态标志,下面是控制标志:
df:方向标志,控制数据串操作指令的步进方向
if:中断允许标志
tf:跟踪标志,为调试程序而设置的,喜欢破解的人要特别注意这个

 

二、寻址方式:
  这个东西非讲不可,没办法,理解起来有困难,我尽量说清楚把!
 
  1、固定寻址
  这种方式,操作数隐藏在指令中,例如,daa,操作数隐含在al中

  2、立即寻址
  用来表示常数,例如:
  mov ax,9    ;9为立即数
  mov ax 1234h ;1234h为立即数,

  3、寄存器寻址
  例如:mov ax,cx
  执行前ax=9602h,cx=2081h
  执行后ax=2081h.

  4、存储器寻址
  这种方式下,操作数一般是代码段之外的数据段、堆栈段,附加段中的存储单元,指令给出的存储单元的地址或表达式。一般而言,一条指令的目的操作数和原操作数不能同为存储器操作数。存储器寻址又分为5种:

  直接寻址:操作数的有效地址由指令直接给出,是带有方括号的常量或变量。        物理地址pa=16*(ds)+偏移地址nn
  例如:
  mov al,[1000h] 将ds段的1000h单元的内容传到al,注意方括号和不加方括号的区别。

   mov ax,[1000h]
   将ds段的1000h内容传到ax,注意ah,al的内容。另外,不要忽视物理地址,这是很总要的信息,破解还是编程,都必须考虑到这个东西。
  
   mov al,es:[2000h] 表示将es段的2000h内容传到al,这叫段超越前缀。


寄存器间接寻址:
格式:[bx,bp,si或di].地址由基址寄存器或变址寄存器给出
如果指令中使用的是bx,si,di则用ds作为段地址
pa=16*(ds)+(bx/si/di)
例如:mov al,[bx] 设bx的内容为1000h,则把ds段的1000h的内容传到al
如果用bp,则用ss做段地址
pa=16*(ss)+(bp)
这种寻址方式一般用来对一维数组操作,改变bx等寄存器的值就可以对连续的存储器单元操作。

以后的就有点复杂了,注意看了,

基址寻址:
格式:偏移量[bx或bp]
例如:mov al,80h[bp] 设bp内容=2040h,则将堆栈段的20c0单元的内容传到al
为什么?因为在16进制下2040h+80h=20c0h不信可以到windows计算器中试一试。其实这条语句等同于mov al,[80h+bp]
操作数的有效地址ea=(bx)/(bp)+偏移量


变址寻址
格式:偏移量[si或di]
操作数的有效地址ea=(si)/(di)+偏移量
是不是和上面差不多?
我们来看一个操作数组的例子:
mov ax,array1[si]
mov array2[di],ax
懂了么? 为什么不能mov array2[di] array1[si]? 因为两个操作数不能同为变量。

别急,这里我没有给出这两种方式的物理地址,算是给大家的一个题目,很容易的,想想看!

 

基址变址寻址
其实就是上面两个结合起来
格式:偏移量[bx/bp + si/di]
pa=16*ds+(bx/bp + si/di  +偏移量)
或者16*ss+(bx/bp + si/di  +偏移量)
注意bx和bp选择的不同,段地址会不同,前者用ds,后者用ss

好了,就这么多,看着是有些头痛,有什么不懂就回帖问我吧,本来是要画图的,我偷了懒。
初学者慢慢看,多看几次,别想一次看懂,有信心就可以了!下一章我们讲循环语句,好了,睡觉去了,说不定明天要点名了。

0 0

相关博文

我的热门文章

img
取 消
img