如何在x86中编写C'&&'运算符?例如:
int a = ...
int b = ...
int c = a && b;
Run Code Online (Sandbox Code Playgroud)
相当于x86中的最后一行是什么?
编辑:我想在没有任何跳跃的情况下完成上述操作.
编辑:g ++生成这个,但我不明白:
testl %edi, %edi
setne %dl
xorl %eax, %eax
testl %esi, %esi
setne %al
andl %edx, %eax
Run Code Online (Sandbox Code Playgroud)
bdo*_*lan 10
以下是GCC如何实现它-O3.
movl 8(%esp), %edx ;; load argument into edx
xorl %eax, %eax ;; eax = 0
movl 4(%esp), %ecx ;; load other argument into ecx
testl %edx, %edx ;; Is EDX nonzero?
setne %al ;; al = 1 if Z = 0
xorl %edx, %edx ;; EDX = 0
testl %ecx, %ecx ;; Is ECX nonzero?
setne %dl ;; dc = 1 if Z = 0
andl %edx, %eax ;; edx &= eax
Run Code Online (Sandbox Code Playgroud)
请注意,此代码不会短路; 这是因为在这种情况下,GCC可以证明第二个参数没有副作用.如果第二个参数有副作用,则必须使用跳转来实现它.例如:
int test(int *a, int *b) {
return (*a)++ && (*b)++;
}
Run Code Online (Sandbox Code Playgroud)
变为:
test:
pushl %ebx ;; save ebx
movl 8(%esp), %eax ;; load a into eax
movl 12(%esp), %ecx ;; load b in to ecx
movl (%eax), %edx ;; *a -> edx
leal 1(%edx), %ebx ;; ebx = edx + 1
movl %ebx, (%eax) ;; *a <- ebx
xorl %eax, %eax ;; eax = 0
testl %edx, %edx ;; if the old value of *a was 0...
je .L2 ;; jump to the end
movl (%ecx), %eax ;; *a -> eax
testl %eax, %eax ;; does *a = 0?
leal 1(%eax), %edx ;; edx = *a + 1 (does not set flags!)
setne %al ;; al = 1 if Z (ie, if a = 0 at the testl above)
movl %edx, (%ecx) ;; save edx to *a (increment *a)
movzbl %al, %eax ;; zero-extend al to eax
.L2:
popl %ebx ;; restore ebx
ret ;; return
Run Code Online (Sandbox Code Playgroud)