程序的机器级表示

条件分支

int abs(int a, int b) {
    if (a > b) {
        return a - b;
    } else {
        return b - a;
    }
}

条件控制

_abs:
    cmpl    %esi, %edi
    jle     L2
    movl    %edi, %eax
    subl    %esi, %eax
    ret
L2:
    movl    %esi, %eax
    subl    %edi, %eax
    ret

条件传送

_abs:
    movl    %edi, %eax
    subl    %esi, %eax
    movl    %esi, %edx
    subl    %edi, %edx
    cmpl    %esi, %edi
    cmovle  %edx, %eax
    ret

循环

do-while

int sum(int n) {
    int res = 0;
    do {
        res += n;
        n -= 1;
    } while (n > 0);
    return res;
}
_sum:
    movl    $0, %eax
LOOP:
    addl    %edi, %eax
    subl    $1, %edi
    cmpl    $0, %edi
    jg      LOOP
    ret

while

int sum(int n) {
    int res = 0;
    while (n > 0) {
        res += n;
        n -= 1;
    }
    return res;
}

for

int sum(int n) {
    int res = 0;
    for (; n > 0; n--) {
        res += n;
    }
    return res;
}

while 和 for循环jump to middle汇编实现

_sum:
    movl    $0, %eax
    jmp     TEST
LOOP:
    addl    %edi, %eax
    subl    $1, %edi
TEST:
    cmpl    $0, %edi
    jg      LOOP
    ret

while 和 for循环guarded-do汇编实现

_sum:
    movl    $0, %eax
    cmpl    $0, %edi
    jle     DONE
LOOP:
    addl    %edi, %eax
    subl    $1, %edi
    cmpl    $0, %edi
    jne     LOOP
    ret
DONE:
    ret

值传递

#include <stdio.h>

int increased(int x) {
    x += 1;
    return x;
}

int main() {
    printf("%d\n", increased(0));
    return 0;
}
_increased:
    movl    %edi, %eax
    addl    $1, %eax
    retq

   .globl  _main
_main:
    pushq   %rbp
    
    movl    $0, %edi
    callq   _increased
    leaq    L_.str(%rip), %rdi
    movl    %eax, %esi
    callq    _printf
    
    movb    $0, %al
    
    popq    %rbp
    retq

L_.str:
    .asciz    "%d\n"

指针传递

#include <stdio.h>

void increase(int *x) {
    *x += 1;
}

int main() {
    int x = 0;
    increase(&x);
    printf("%d\n", x);
    return 0;
}
_increase:
    addl    $1, (%rdi)
    retq

   .globl  _main
_main:
    pushq   %rbp
    movq    %rsp, %rbp
    subq    $16, %rsp
    
    movl    $0, -8(%rbp)
    leaq    -8(%rbp), %rdi
    callq   _increase
    leaq    L_.str(%rip), %rdi
    movl    -8(%rbp), %esi
    callq   _printf
    
    movb    $0, %al
    
    addq    $16, %rsp
    popq    %rbp
    retq

L_.str:
    .asciz    "%d\n"

局部变量

int function() {
    int a = 1;
    int b = 2;
    int c = 3;
    return a + b + c;
}
_function:
    pushq   %rbp
    pushq   %rbx
    
    movl    $1, %ebp
    movl    $2, %ebx
    movl    $3, %eax
    addl    %ebp, %eax
    addl    %ebx, %eax

    popq    %rbx
    popq    %rbp
    
    retq

递归

int fibonacci(int n) {
    if (n == 0) {
        return 1;
    }
    if (n == 1) {
        return 1;
    }
    return fibonacci(n - 1) + fibonacci(n - 2);
}
_fibonacci:
    pushq   %rbp
    pushq   %rbx
    
    cmpl    $0, %edi
    jne      L2
    movl    $1, %eax
    
    popq    %rbx
    popq    %rbp
    ret
L2:
    cmpl    $1, %edi
    jne     L3
    movl    $1, %eax
    
    popq    %rbx
    popq    %rbp
    ret
L3:
    movl    %edi, %ebp
    subl    $1, %edi
    callq   _fibonacci
    movl    %eax, %ebx
    movl    %ebp, %edi
    subl    $2, %edi
    callq   _fibonacci
    addl    %ebx, %eax
    
    popq    %rbx
    popq    %rbp
    ret

数组

#include <stdio.h>

int subscript_get(int *a, int i) {
    return a[i];
}

void subscript_set(int *a, int i, int x) {
    a[i] = x;
}

int main() {
    int a[5];
    subscript_set(a, 3, 3);
    printf("%d\n", subscript_get(a, 3));
    return 0;
}
_subscript_get:
	movl	(%rdi,%rsi,4), %eax
	retq

_subscript_set:
	movl	%edx, (%rdi,%rsi,4)
	retq

    .globl  _main
_main:
    pushq   %rbp
    movq    %rsp, %rbp
    pushq   %rbx
    subq    $40, %rsp
    
    leaq    -48(%rbp), %rdi
    movl    $3, %esi
    movl    $3, %edx
    callq   _subscript_set
    movl    $3, %esi
    callq   _subscript_get
    leaq    L_.str(%rip), %rdi
    movl    %eax, %esi
    callq   _printf
    
    movb    $0, %al

    addq    $40, %rsp
    popq    %rbx
    popq    %rbp
    retq

L_.str:
    .asciz    "%d\n"

结构体

#include <stdio.h>

struct T {
    int i;
    char c;
    int a[3];
    char *s;
};


int main() {
    struct T t = {1, 'c', {0, 1, 2}, "hello"};
    printf("%d, %c, %d, %s\n", t.i, t.c, t.a[0], t.s);
    return 0;
}
    .globl    _main
_main:
    pushq   %rbp
    movq    %rsp, %rbp
    subq    $48, %rsp
    
    movq    l___const.main.t(%rip), %rax
    movq    %rax, -40(%rbp)
    movq    l___const.main.t+8(%rip), %rax
    movq    %rax, -32(%rbp)
    movq    l___const.main.t+16(%rip), %rax
    movq    %rax, -24(%rbp)
    movq    l___const.main.t+24(%rip), %rax
    movq    %rax, -16(%rbp)
    movl    -40(%rbp), %esi
    movsbl  -36(%rbp), %edx
    movl    -32(%rbp), %ecx
    movq    -16(%rbp), %r8
    leaq    L_.str.1(%rip), %rdi
    callq   _printf
    
    movb    $0, %al
    
    addq    $48, %rsp
    popq    %rbp
    retq

L_.str:
    .asciz    "hello"

    .section    __DATA,__const
l___const.main.t:
    .long   1
    .byte   99
    .space  3
    .long   0
    .long   1
    .long   2
    .space  4
    .quad   L_.str

L_.str.1:
    .asciz    "%d, %c, %d, %s\n"