清零的方法有很多,XOR或者用AND等等,有什么区别吗

number_lock 2012-01-17 11:54:22
就好比INC和ADD 1有一些微妙的区别一样,不同的清零方式是否有什么不同?那种最常用,最不容易出错?
...全文
1119 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
Guilty 2012-01-19
  • 打赏
  • 举报
回复
INTEL的一些手册都不建议用INC,让你用ADD 1
至少在新的CPU上,用完INC立即测试标志位会严重影响速度,但INC后面跟一条ADD,XOR之类的就没事了。
当时INTEL设计INC DEC的时候出了问题,不影响C标志,后来一定很后悔,但是因为兼容性问题只能保留这个问题了。
Guilty 2012-01-19
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 hili210 的回复:]
如果是赋值给AL或别的8位寄存器,指令大小就也是2个字节。

因为如果要赋值给AX,AX是16位的寄存器,也就是说,即使是赋值0,那么,编译器也要把0编译成大小为16位的,因为必须要大小相同才能赋值。

所以,如果是对16位的寄存器赋值0,XOR AX , AX 在空间上就有1个字节的优势
[/Quote]
我记得32位系统里 MOV 0是4个字节的0,但ADD 0只有一个字节的0,因为对-128到127有个单独的指令。
其实一些CPU用MOV立即数可能更快,因为解码阶段就完成了,而XOR需要占用执行单元。
Guilty 2012-01-19
  • 打赏
  • 举报
回复
VC 6可以用MASM,也可以用C里面INLINE汇编
number_lock 2012-01-19
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 hili210 的回复:]
使用Debug输入-a命令,输入
MOV AX , 0
XOR AX , AX
AND AX , 0


再使用-u查看,
MOV AX , 0 指令为B80000,占3个字节
XOR AX , AX 指令为31C0,占2个字节
AND AX , 0 指令为250000,占3个字节


还是XOR比较有优势,因为其他2个都是用了数字,也就是那4个0,光0就占了4个字节,所以……
[/Quote]
刚想结贴又想到个问题,敢问你用的是什么编译环境?我的老师让我们用wave6000,我用的非常之蛋疼。你的VC6.0是不是可以兼容汇编啊?
hili210 2012-01-18
  • 打赏
  • 举报
回复
使用Debug输入-a命令,输入
MOV AX , 0
XOR AX , AX
AND AX , 0


再使用-u查看,
MOV AX , 0 指令为B80000,占3个字节
XOR AX , AX 指令为31C0,占2个字节
AND AX , 0 指令为250000,占3个字节


还是XOR比较有优势,因为其他2个都是用了数字,也就是那4个0,光0就占了4个字节,所以XOR会有优势

.
hili210 2012-01-18
  • 打赏
  • 举报
回复
"光0就占了4个字节",

打错,

是2个字节,嘿嘿,脑子不小心短路了。。。
hili210 2012-01-18
  • 打赏
  • 举报
回复
如果是赋值给AL或别的8位寄存器,指令大小就也是2个字节。

因为如果要赋值给AX,AX是16位的寄存器,也就是说,即使是赋值0,那么,编译器也要把0编译成大小为16位的,因为必须要大小相同才能赋值。

所以,如果是对16位的寄存器赋值0,XOR AX , AX 在空间上就有1个字节的优势
hili210 2012-01-17
  • 打赏
  • 举报
回复
一个是楼上所说的。

还有就是,速度快慢与易理解的问题,楼主可以用循环试个几千几万甚至更高的运算,进行测试一下所需时间就基本明白了

一般在微机原理中,推荐的是用XOR AX , AX 的方式,因为他们都只使用了寄存器,而没用到内存。

而在王爽的汇编中,一般是用MOV AX , 0 的方式,因为这样更好理解,虽然速度可能比不上XOR,

但是,毕竟是小程序,在速度不是很重要的情况下,为了教学上的好理解,就使用这种方式。


我看过一些微软的系统源码,像类似这种的汇编,或嵌入式汇编,速度就显得比较重要。
masmaster 2012-01-17
  • 打赏
  • 举报
回复
对标志位的影响不一样。
number_lock 2012-01-17
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 hili210 的回复:]
抽了点时间用汇编做了个,下面的2组数据表示在5秒钟内执行了多少次,也是不一定的


; XOR (DX) = 2637H
; AND (DX) = 3A32H

; XOR (DX) = 1355H
; AND (DX) = 2318H



了解下就行。哪个好理解就用哪个好了



Assembly code



assume cs:code

cod……
[/Quote]

辛苦辛苦!既然这个时间复杂度的问题上这么纠结蛋疼,换个问法,XOR AX , AX和AND AX , 0的空间复杂度上有差别吗,换句话说两条指令在代码段中占据的空间大小有区别吗
hili210 2012-01-17
  • 打赏
  • 举报
回复
抽了点时间用汇编做了个,下面的2组数据表示在5秒钟内执行了多少次,也是不一定的


; XOR (DX) = 2637H
; AND (DX) = 3A32H

; XOR (DX) = 1355H
; AND (DX) = 2318H



了解下就行。哪个好理解就用哪个好了





assume cs:code

code segment


start:
XOR DX , DX
MOV BX , 5000 ; 5秒
CALL Sleep

MOV AX , 4C00H
INT 21H




Sleep:

; 暂停(休息)子程序
; 入口参数 bx(单位毫秒)
; 例:需要一秒延时,将bx置为1000,调用子程序即可


MOV AH , 2CH ; 2CH中断为取得系统时间中断
INT 21H
MOV byte ptr CS:[_cmptime] , DL

_Sleep1:

XOR DI , DI ; 额外的测试
INC DX ; 累加1次

MOV AH , 2CH
INT 21H
CMP byte ptr CS:[_cmptime] , DL
JE _Sleep1
SUB BX , 55
CMP BX , 0
JG Sleep

RET

_cmptime:
NOP



code ends


end start

hili210 2012-01-17
  • 打赏
  • 举报
回复

我用VC6.0嵌入汇编做了下测试,XOR AX , AX和AND AX , 0 速度几乎相当

有时XOR高有时AND高,这可能与C++有关,用纯汇编做可能会好些,不过我时间不多

经过几次执行,时间差距在 -20~20毫秒之间,有时相同




#include <stdio.h>
#include <windows.h>

int main()
{
int i = 0;
DWORD t1 , t2;


t1 = GetTickCount(); // 记录开始时间
for(i = 0; i < 100000000; ++i)
{
_asm
{
XOR AX , AX
}
}
t2 = GetTickCount(); // 记录结束时间
printf( "XOR:%ld\n" , t2 - t1 );



t1 = GetTickCount(); // 记录开始时间
for(i = 0; i < 100000000; ++i)
{
_asm
{
AND AX , 0
}
}
t2 = GetTickCount(); // 记录结束时间
printf( "AND:%ld\n" , t2 - t1 );


return 0;
}

number_lock 2012-01-17
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 hili210 的回复:]
如果说是AND AX , 0 的话也不算用到内存,这是寻址的立即寻址方式,操作数写在指令中,执行速度也比较快。


XOR AX , AX 则是寄存器寻址。


具体哪种快慢也不一定,这两种都是寻址较快的2种,楼主可以用循环测试下,输出他们的执行N次后的时间,这样也可以锻炼下编程。
[/Quote]

有点儿困难。。循环倒还好说,计时如何实现?是用程序实现,还是自己看着表数着o(╯□╰)o
masmaster 2012-01-17
  • 打赏
  • 举报
回复
楼上说的在理! 从存贮设备层次结构上来说,如果CPU含有三级缓存的话,那么寄存器就是L0级,而内存则是L4级,存取速度上好很多!
hili210 2012-01-17
  • 打赏
  • 举报
回复

如果说是AND AX , 0 的话也不算用到内存,这是寻址的立即寻址方式,操作数写在指令中,执行速度也比较快。


XOR AX , AX 则是寄存器寻址。


具体哪种快慢也不一定,这两种都是寻址较快的2种,楼主可以用循环测试下,输出他们的执行N次后的时间,这样也可以锻炼下编程。
number_lock 2012-01-17
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 hili210 的回复:]
一个是楼上所说的。

还有就是,速度快慢与易理解的问题,楼主可以用循环试个几千几万甚至更高的运算,进行测试一下所需时间就基本明白了

一般在微机原理中,推荐的是用XOR AX , AX 的方式,因为他们都只使用了寄存器,而没用到内存。

而在王爽的汇编中,一般是用MOV AX , 0 的方式,因为这样更好理解,虽然速度可能比不上XOR,

但是,毕竟是小程序,在速度不是很重要的情况……
[/Quote]

有关XOR AX , AX 只使用了寄存器,而没用到内存。可否再具体点儿?如果是AND AX , 0,这样是不是就用到了内存?它是怎样使用内存的?这问题可能白痴点儿。。我是初学中的初学,求指点

21,496

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧