我刚刚使用if语句尝试了一个简单的C程序并分析了它的程序集.但是,当使用-O2标志进行编译时,它的行为会有很大差异.
相同的C代码是: -
#include<stdio.h>
int main(int argc, char **argv) {
int a;
if(a<0) {
printf("A is less than 0\n");
}
}
Run Code Online (Sandbox Code Playgroud)
而相应的组装是: -
main:
push %ebp
mov %ebp, %esp
sub %esp, 8
and %esp, -16
sub %esp, 16
test %eax, %eax
js .L4
leave
ret
.p2align 4,,15
.L4:
sub %esp, 12
push OFFSET FLAT:.LC0
call puts
add %esp, 16
leave
ret
.size main, .-main
.section .note.GNU-stack,"",@progbits
.ident "GCC: (GNU) 3.4.6"
Run Code Online (Sandbox Code Playgroud)
我读到该test
指令基本上只执行两个操作数的逻辑AND.我还读到,当前js
一条指令中的符号发生变化时,指令会执行跳转.因此,test
使用eax的eax会给出0
或者1
跳跃将取决于此.
我不明白它是如何用于分支的.有人可以解释这是如何工作的?
San*_*dri 11
当符号发生变化时,JS不跳转,如果符号标志为1则跳转.
如果最后一次操作的结果为负,则符号位为on(2的补码中的负数在1中具有最高有效位).
因此,如果AND运算在两个负整数(-1和-1)之间,则最后一位将为1(符号标志),因此跳转.如果数字为正数,则最后一位为0,则不会进行跳转.