现在的位置: 首页 > 综合 > 正文

似曾相识——记录NASM中的非、与、或

2013年06月01日 ⁄ 综合 ⁄ 共 1519字 ⁄ 字号 评论关闭
 

似曾相识——记录NASM中的非、与、或

刺猬@http://blog.csdn.net/littlehedgehog

Nasm在一定程度上跟C是相似的。比如在预编译文件头%include,比如关键字extern等。这次的非与或也跟C大致相当。

先贴上一些代码。(节选自《自己动手写操作系统》 P274 )

in    al, INT_M_CTLMASK     
or    al
, 1
    
out    INT_M_CTLMASK
,
 al    


in    al
,
 INT_M_CTLMASK        
and    al
,
 0xFE    
out    INT_M_CTLMASK
, al

这两段代码分别是屏蔽时钟中断 和 再次打开时间中断,即是用OCW1写入8259A。第一段是在INT_M_CTLMASK (即21h端口) 中bit0设为1(关闭该端口),同样第二段是把bit0设为0,代码很简单,但是为了我们的内核扩展性更好,我们模仿Minix的内核源码把它处理成宏。下面是该宏的部分代码:

 

hwint_master    1
    call    save

    in    al
, INT_M_CTLMASK       ; ┓
    or    al, (1 << %1)                     ; ┣ 屏蔽当前中断
    out    INT_M_CTLMASK, al    ; ┛

    mov    al, EOI                     ; ┓置EOI位
    out    INT_M_CTL, al        ; ┛
    sti    ; CPU在响应中断的过程中会自动关中断,这句之后就允许响应新的中断
    push    %1                 

    call    [irq_table + 4 * %1]                         ; ┣ 中断处理程序
    pop    ecx           

    cli

    in    al
, INT_M_CTLMASK    ; ┓
    and    al, ~(1 << %1)    ; ┣ 恢复接受当前中断
    out    INT_M_CTLMASK, al    ; ┛

只关心那一段粗体字,其实跟上面代码大致是一样的,我们来看看下面那个"~",进入我们正题了。这里给出nasm的中文手册关于~的解释:

这些只作用于一个参数的一元运算符是NASM的表达式语法中优先级最高的。
'-'把它的操作数取反,'+'不作任何事情(它只是为了和'-'保持对称),
'~'对它的操作数取补码

如果是取补码的话,那么按照补码的规定 比如此时时钟中断发生传入数据是0,那么and    al, ~(1 << %1)   执行的就是 and al,~1  1的补码还是1,正数的补码是不变的。最终的程序是 and  al,1   这和上面原来未变更的代码是完全背道而驰的。我们不妨作如下一个实验:

测试代码:

nop    
nop
mov    al
,(1<<0
)
mov    al
,-(1
)
mov    al
,~(1<<0)

我们再来看看它的反汇编代码:

看看截图中红色框中的内容 ~1 并不是取得1的补码 而是按位取反而已。是不是有点似曾相识? C语言啊 C语言就是这样规定! 我们顺便来看看 "-1" 又是什么意思。0xFF即是(11111111b),把-1的绝对值取反,然后再加一,这个是什么呢?就是 负一 的补码啊  又是跟C语言一致的。

 结论: ~在nasm中是按位取反,而- 就是普通的取相反数了,跟C一样

 

《自己动手写操作系统》读书笔记系列

抱歉!评论已关闭.