数据处理的两个基本问题
由于浏览器的原因,本人费劲写的 第七篇日志被网络无情的封杀了= =,(+﹏+)~狂晕,好吧接着写第八篇。。。
现在我们对过去所学的基本内容进行一下梳理,我们先来梳理一下基本寄存器的用法和汇编语言格式。
在访问内存地址的时候,我们只能用 bx,si,di,bp这四个寄存器 其实就是这种寻址方式 :mov ax,[bx] mov ax,[bp] mov ax,[si] mov ax,[di] 是不是我们从来没有提到过 mov ax, [cx] mov ax,[ax] mov ax,[dx] mov ax,[ds]等指令格式呢???当然下列指令是正确的
mov ax, [bx]
mov ax,[bp]
mov ax,[si]
mov ax,[di]
mov ax,[bx+si]
mov ax,[bx+di]
mov ax,[bp+si]
mov ax,[bp+di]
mov ax,[bx+di+num]
但是 这样做就是不对的
mov ax, [bx+bp] mov ax,[si+di]
根据指令的不同我们可以判断数据执行时所在的位置 如下
mov ax,[0] 我们知道数据是从内存里取出来的。
mov ax,ax 我们知道数据从cpu内部 因为寄存器实在cpu内部的
mov ax, 1 我们知道数据也是从菜谱内部取出来的 ,是从指令缓冲器里取出来的
进行一下寻址方式的综合介绍
像这种 mov ax,[num] 这就是直接寻址
mov ax,[寄存器]这就是寄存器间接寻址
mov ax, [寄存器+num]这就是寄存器相对寻址
mov ax, [bx+si]等 这就是基址变址寻址方式
mov ax ,[bx+si+num]这就是相对基址变址寻址
关于指令中处理数据的长度
一般 我们都在指令中指明了 例如mov ax, 【0】 就是将0 1 两个内存地址中的信息传送到 ax 中去因为 ax 能存储16位二进制信息,我们是一目了然的
mov al ,【0】这个我们也是一目了然的看出是字节操作
指令中用到了寄存器我们就能很好的看出是什么操作 但是有些操作没有用到寄存器我们就很难判断是什么操作了。这种情况下cpu也是看不出是字节操作还是字操作 。这就需要我们特别指明汇编指令数据的操作长度了。
mov 【0】,1我们就很难判断是将双字节还是单字节数据1传送到内存中,所以cpu也不知道 如何对数据进行传送 这就需要我们进行如下操作
mov word ptr [0],1我们很容易知道是将子单元数据传送 当然也是可以进行 byte ptr 表示字节长度的传送 这样我们就指明了进行操作的数据长度,cpu也就能够进行操作了
在介绍一条比较复杂的汇编指令 除法指令 div
1用此指令的时候我们要注意 除数的8位和16位是不同的。。而且除数一定要在寄存器或内存单元中
2被除数默认放在ax中或dx 与ax 中 如果除数是8位的那么被除数就是16位的,默认放到了ax中去 若是除数是16位的那么被除数就是32位的默认放到了 dx 和ax中去了 dx存放高字单元ax存放低字单元
3结果的存放 一般规则就是存放结果的器件的低部分存放商,高部分存放余数,例如 除数是8位 被除数必然是16位那么余数存放到ah中商放到al中去 相应的除数是16位那么被除数必然是32位 存放到 dx和ax中去 那么结果中的余数放到了dx中 商放到了ax中去。。。。
我们同时要注意除法指令是但操作数指令,他的被除数必然要先放到相应的寄存器里去,所以该条指令就成了单操作数指令了例如 mov ax,12 div byte ptr 【0】
我们应用这条指令的时候一定要注意除法溢出问题,这个貌似有点小麻烦,呵呵。。以后我们会涉及到的。
我们在介绍一条伪指令来解决我们在段中定义数据使得麻烦。。
我们在定义数据时总会用到 空白区尤其是进行字符串的传送时 那么例如以前我们定义 16个0字单元我们都是进行 dw 0 0 0.。。00(反正此处要写16个0)
但是我们利用dup伪指令就不用这么麻烦了 我们只要定义成这样就行了
dw 16 dup(0) 就行了 相应的我们定义字节单元也是这样。 db 16 dup (0)
这样我们就可以定义更大的数据空间,,而不用画那么多圈圈了。。呵呵。。敬请斧正,,敬请期待续集,,谢谢交流。。。。