testl eax对抗eax?

时间:2020-03-06 14:51:25  来源:igfitidea点击:

我试图了解一些组装。

汇编如下,我对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。