Dragon  
Dragon
日历
<2008年9月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011
统计
  • 随笔 - 58
  • 文章 - 0
  • 评论 - 55
  • 引用 - 0

导航

常用链接

留言簿(3)

随笔分类(58)

随笔档案(58)

搜索

  •  

最新评论

阅读排行榜

评论排行榜

 

在汇编源程序中,数据不能以字母开头,故要加0识别!

debug程序开始时DS指向的是PSP的头地址,而CS=DS+10H

不能将一个数值直接送入段寄存器,要通过其它寄存器进行传送!

(N/16+1)*16 意思是总取多16个字节存放多出的字节.N+16不等价左边的式子.
它等价于(int(N/16)+1).

一般来说,当我们要暂存数据时,都应该使用栈!

(1)只有bx,si,di,bp用在[]里进行内在单元的存取.
(2)bx,si,di,bp只能以bx与si,bx与di,bp与si,bp与di四种组合出现
形像些:
    si
  /
bx
  \
    di

    si
  /
bp
  \
    di
(3)只要在[]中使用寄存器bp,而指令中没有显性地给出段地址,段地址就默认在ss中,其它的    是不是默认存放在ds中?

数据处理的分类:写入,读取,运算!
数据存在的三个地方:CPU内,内存,端口!

push只进行字操作,pop呢?


用dd定义的数的存放,如100001它的十六进制为186A1H,则它在内存的存放形式是
A1 86 01 00
刚刚好是32位,和我们的逻辑000186A1不一样(规律:倒过来).
在一个数据段里定义的数据是连续存放的,但要看清楚它们是什么类型(dd,dw,db).


db '1634'里面一个字符占一个字节,保存的是相应的ACSII码.

 

loop指令是先把CX寄存器的值减1然后再判断是否是0

 

assume cs:code
code segment
       mov ax,4c00H
       int 21H
start: mov ax,0
    s: nop
       nop

       mov di,offset s     ;以下四行复制s2的第一条指令给s
       mov si,offset s2    ;刚刚好覆盖了s的两条nop指令
       mov ax,cs:[si]      ;复制过去的内容是:"向前或向后移动多少"
       mov cs:[di],ax

   s0: jmp short s
   s1: mov ax,0
       int 21H
       mov ax,0

   s2: jmp short s1        ;机器码EBF6;意思是"向前移动10d个字节"
       nop
code ends
end start

;9D:0000 B8004C        MOV     AX,4C00
;9D:0003 CD21          INT     21
;9D:0005 B80000        MOV     AX,0000
;9D:0008 EBF6          JMP     0000        EBF6复制过来后前移10个字节即跳到0000
;9D:000A BF0800        MOV     DI,0008
;9D:000D BE2000        MOV     SI,0020
;9D:0010 2E            CS:
;9D:0011 8B04          MOV     AX,[SI]
;9D:0013 2E            CS:
;9D:0014 8905          MOV     [DI],AX
;9D:0016 EBF0          JMP     0008
;9D:0018 B80000        MOV     AX,0000
;9D:001B CD21          INT     21
;9D:001D B80000        MOV     AX,0000

对call指令的一些理解:
call word ptr 内存单元地址
书上理解:
push IP
jmp word ptr 内存单元地址
我的理解:
(1)IP的值先变成CALL指令后的第一个字节的偏移地址,然后才被压入栈;
(2)压入后再改变IP的值,即(IP)=内存单元地址的值.


call dword ptr 内存单元地址
书上理解:
push cs
push ip
jmp dword ptr 内存单元地址

开始是将此时的CS,IP(IP应该是CALL命令后的第一个字节)压入栈,CS是先压入钱的,
然后跳到内存单元中内容所指的地址,
即CS=((内存单元地址)+2),IP=(内存单元)//其实这两个是JMP指令的理解.

 


对X/N=int(H/N)*65536+(rem(H/N)*65536+L)/N的理解
int(H/N)*65536求出的是高16位的值,即 16位的值0000
后面16位是低16位的值,因为后面的商不会超过16位,求出的商就是低16的值,加到0000上
而(rem(H/N)*65536+L)/N算得的余数就是本X/N的余数.
注意*65536的含义是向左移多少位,后面的补零.

 

先算16进制再算十进制!

 

int是将子程序装入内在先,然后通过代号进行调用.(静态)
而call就如动态执行这样,等到运行时才装入内存.(动态)


P246的中断例程的理解
lp:push bp         ;此时栈里的情况是:bp ip cs 标志寄存器
   mov bp,sp      
   dec cx
   jcxz lpret
   add [bp+2],bx   ;因为bp默认的段寄存器是ss,故使用了bp,而+2就指向了ip的值.
lpret:
   pop bp
   iret            ;由cx 来决定是循环还是向下继续执行,

 


编写中断例程的步聚:
(1)先将代码复制到指定的位置,注意这里要指出要复制字节的长度
(2)再把指定的代码存放位置放到向量表中,因为是通过向量表进行访问的.
(3)你可以编写你的中断例程了!记得开始与结尾标志!

 

在in与out指令中,只能使用ax或al来存放从端口中读入的数据或要发送到端口中的数据,访问8位端口时用AL,访问16位端口时要用AX.

shl,shr指令移位多于一位时一定要将移的位数放在cl里.

BCD码4位确定一个数,如26的BCD码为0010 0110

 

7.8  已知对应于中断类型码为18H的中断服务程序存放在0020H:6314H开始的内存区域中,求对应于18H类型码的中断向量存放位置和内容。

在编写程序时,为什么通常总要用STI和CLI中断指令来设置中断允许标志?8259A的中断屏蔽寄存器IMR和中断允许标志IF有什么区别?

【解答】偏移地址EA=18H×4=60H,18H中断向量在中断向量表中的入口地址为00000H+60H=00060H。中断服务程序存放在0020H:6314H开始的内存区域中,所以(00060H)=0020H,(00061H)= 6314H。

IF是8086微处理器内部标志寄存器Flags的中断允许标志位。若IF=1,则CPU可以接受中断请求;若IF=0,8086就不接受外部可屏蔽中断请求INTR引线上的请求信号。在编写程序时,用STI指令使中断允许标志位IF=1,目的是使CPU能够接受中断请求,或实现中断嵌套。而用CLI指令使中断允许标志位IF=0,则可以关中断,使CPU拒绝接受外部中断请求信号。

如果8259A的中断屏蔽寄存器IMR中的某位为1,就把这一位对应的中断请求输入信号IR屏蔽掉,无法被8259A处理,也无法向8086处理器产生INTR请求。


注意:在后面加有":"的地址标号,只能在代码段中使用,不能在其他段中使用.

$表示的是本行地址,
$$则表示开始汇编的地址.

 

2.3总结:
执行mov指令不改变CS寄存器
执行jmp 段地址:偏移地址   改变CS和IP
执行jmp 寄存器   只改变IP不改变CS

 


实验五总结:
还没加载程序前:
CS:IP指向程序段的第一条指令,故CS可以知道.
SS=CS-2
DS=SS-10H ;这个知道有没有用?

加载后:
SS=CS-1;
DS=CS-2;

posted on 2008-09-02 20:09 Dragon 阅读(385) 评论(0)  编辑 收藏 引用 所属分类: 汇编

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


 
Copyright © Dragon Powered by: 博客园 模板提供:沪江博客