如何在x86中编写C"&&"运算符?

Mat*_*man 4 c x86 assembly

如何在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)

  • 只需删除cfi垃圾.它仅用于高级调试和C++异常处理. (4认同)