testl eax对抗eax?
我试图了解一些组装。
汇编如下,我对testl
行感兴趣:
000319df 8b4508 movl 0x08(%ebp), %eax 000319e2 8b4004 movl 0x04(%eax), %eax 000319e5 85c0 testl %eax, %eax 000319e7 7407 je 0x000319f0
我试图理解%eax和%eax之间的testl的要点?我认为这段代码的具体内容并不重要,我只是想了解一下自身的测试,难道该价值永远不会是真的吗?
解决方案
它测试" eax"是否为0,大于或者等于0。在这种情况下,如果eax为0,则进行跳转。
" test"的意思是将参数和在一起,并检查结果是否为零。因此,此代码测试EAX是否为零。如果为零,je
将会跳转。
顺便说一句,它生成的指令比" cmp eax,0"要小,这就是编译器通常会以这种方式执行此指令的原因。
如果eax为零,它将执行条件跳转,否则它将在319e9继续执行
测试指令在操作数之间进行逻辑"与"运算,但不会将结果写回到寄存器中。仅标志被更新。
在示例测试eax中,如果eax为零,则eax将设置零标志,如果设置了最高位,则将设置符号标志,以及其他一些标志。
如果设置了零标志,则跳转相等指令(je)。
我们可以将代码转换为更具可读性的代码,如下所示:
cmp eax, 0 je somewhere
它具有相同的功能,但需要更多字节的代码空间。这就是为什么编译器发出测试而不是比较的原因。
此代码段来自一个子例程,该子例程被赋予了指向某些内容(可能是某些结构或者对象)的指针。第二行取消对该指针的引用,从该对象本身(可能是一个指针或者一个整数)中获取一个值,该值作为第二个成员存储(偏移量+4)。第三行和第四行将该值测试为零(如果是指针,则为NULL),如果该值为零,则跳过以下几个操作(未显示)。
零测试有时被编码为与立即数立即值零的比较,但是编写此代码的编译器(或者人类?)可能认为考虑所有现代CPU之类的流水线和寄存器重命名操作,testl op运行得更快。它来自同一堆花样,其中包含用XOR EAX,EAX(我在科罗拉多州某人的车牌上看到的!)清除寄存器的想法,而不是明显但可能较慢的MOV EAX#0(我使用较旧的表示法) )。
在asm中,就像perl一样,TMTOWTDI。