汇编杂乱记

1.=======================================================================

DATAS SEGMENT
    ;此处输入数据段代码 
DATAS ENDS

STACKS SEGMENT
    ;此处输入堆栈段代码
    DW 16 DUP (0)
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,STACKS
    MOV SS,AX
    MOV SP,32;这边自己设置一个堆栈
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;此处输入代码段代码
    MOV AX,0
    PUSH AX ;将AX放入堆栈中
    POPF ;将堆栈中的栈顶的值取出来,让后放入到标志寄存器中
    MOV AX,0FFF0H
    ADD AX,0010H
    PUSHF ;将标志寄存器中的值放入到对战中
    POP AX ;将堆栈中的值再取出来给AX
    AND AL,11000101B
    AND AH,00001000B ;对AX进行与操作
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;这边是测试代码
    ;直接将寄存器中的值拿出来放到AX中,看是什么样的结果,代码是
    ;
    ;PUSHF
    ;POP AX
    ;
    ;这边,我们直接在DEBUG中进行测试,这边测试后,AX=3202H
    ;这是标志寄存器中的值,也就是二进制的 0011 0010 0000 0010
    ;也就是说标志寄存器中的1,3,5,8中的值原来默认的是1,0,0,0,这是
    ;为什么呢,这边我就真的是不知道了。而原来寄存器中IF的默认值是
    ;1,也就是响应CPU外部的可屏蔽中断发出的中断请求,这是可以理解的
    ;但是为什么1,5位置的默认值是1,这边我真的是不清楚了,不知道哪里
    ;有资料详细的讲明这些东西。TF是单步中断请求标志,如果是按照上面
    ;的这种解释的话,我们在重新的来看一下我们的原来的代码,这边我们
    ;进行一个加法运算,因为进行加法运算后,标志寄存器的值的符号表示
    ;是 NV UP DI PL ZR NA PE CY,对应的值是0 0 0 0 1 0 1 1,如果是这
    ;样的话,我们现在默认,运行加法运算后,其他默认的没有标志位的寄存
    ;器的值是没有改变的,也就是在1,3,5,8中的值还是原来的1,0,0,0,这样
    ;我们得到的AX的值就是0011 0000 0100 0111,既是AX=3047H,但是,
    ;并不是我们想要的3047H,这是为什么呢?很明显的,我们的假设是
    ;错误的,但是,为什么运行加法后,标志寄存器中的1,3,5,12,13,14,15
    ;位置的位也相应的产生了变化呢,现在我们是确定有变化了,但是这是
    ;为什么了,书中对这些空置的标志位没有理会,但是,为什么程序
    ;运行的时候,还要这样子对空置标志位进行运算呢,这真的是匪夷所思
    ;了。或者是另外的一中可能,我对原来的代码理解的不是很透彻,还是
    ;CPU本身运行机制的问题呢。
    ;;;;;;;;;;;;;;
    ;这边从新进行测试,想一下,标志寄存器是放在内存中吗,应该不是的,
    ;按理说应该是和通用寄存器一样,但是他们是放在那里呢,这个真的是不明白,
    ;网上找找看吧,是单独的存放到一个位置吗,是在哪里呢?
    ;寄存器是CPU的内部元件,应该说和内存是独立开来的,这点要明白,而对于
    ;外部寄存器,它是同时具有内寄存器和内存储器的特点。不能看清寄存器,
    ;特别是标志寄存器的变化过程和变化的机制,但是很想知道,现在终于是找到
    
    ;答案了,原来是我自己理解错了,就是那么简单的高位,低位的问题了,但是
    ;自己就是没有缓过来,呵呵,但是现在还是由一个问题了,为什么标志位的
    ;第一位的默认值是1呢,这真的是头大!接下来代码也就简单了,看来是不能随便
    ;的错过什么问题啊,不然是会后悔的,糟糕的
    MOV AH,4CH
    INT 21H
CODES ENDS
    END START
    ;这边执行行到POP AX后,AX 的值是3047H,这是为什么呢,我真的是
    ;不明白了,这些标志寄存器的结构真的是不大了解了。所以这边为了
    ;了解标志寄存器的结构,我这边必须进行一些测试。

2.=======================================================================

DATAS SEGMENT
    DB 16 DUP (0)
DATAS ENDS

STACKS SEGMENT
    ;此处输入堆栈段代码
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV ES,AX
    MOV AX,0F000H
    MOV DS,AX
    ;MOV SI,0FFFFH
    ;MOV DI,15
    ;MOV CX,16
    ;这边我们使用MOVSW进行字符串的传送
    MOV SI,0FFFEH
    MOV DI,14
    MOV CX,8
    STD
    ;REP MOVSB
    REP MOVSW
    MOV AH,4CH
    INT 21H
CODES ENDS
    END START
    ;这边如果我用的是字传送的时候就不可以了呢,我有修改cx为8,
    ;但是,为什么这样是不可以的呢,这个肯定是要搞明白的,这边
    ;我们还是要一个一个的进行简单的测试的。也就是从MOVSW开始进行
    ;测试,然后再找出其中的蹊跷。先看下书怎么说MOVSW的。
   
    ;很兴奋的,这边终于是发现问题了,因为你要知道,这边的SI,DI是相对应的
    ;指向字符串的最后一个字节或者是最后的一个字,如果你使用MOVSB,
    ;那么,SI对应的就是指向字符串的最后的一个字节,但是如果使用的是
    ;MOVSW的话,那么SI对应的就是指向字符串的最后一个字的首地址了,
    ;而这边的字的首地址应该是如上面代码中表示,对应的DI也是同样的原理的
    ;而刚才我没有改过来,SI还是指向字符串的最后的一个字节,但是
    ;我使用的是MOVSW的时候,在程序运行的时候,他们要找到对应的是字
    ;但是对于每一个字(有两个字节组成)的首地址应该是偶数型地址(系统
    ;默认的吧,这个我真的是也不太清楚了,反正就是这样子了,这是硬件
    ;方面的问题吧),所以在运行的时候就出现了问题了。总的来说
    ;MOVSB 和 MOVSW使用的方法是类似的,只是如果字符串是奇数长度的
    ;时候,我们正常使用的是MOVSB,如果是偶数长度的时候,我们就
    ;尽量的时候MOVSW,因为这样子,速度应该是更快的。

3.==========================================================================

这边事BIOS中断例程INT10 的2号中断和9号中断的例子和巩固:

猜你喜欢

转载自blog.csdn.net/qungxue/article/details/6317347