good design of C code & its relative assembly code

看到很overwhelming,快吐血時突然發現自己終於又看完一課,

把看完後該課最好的code design範例貼上, 因為真的太棒了:

#include <cs50.h>
#include <stdio.h>

void cough(int n);
void say(string s, int n);
void sneeze(int n);


int main(void)
{
    cough(3);
    sneeze(3);
}

void cough(int n)
{
    say("cough", n);
}

void sneeze(int n)
{
    say("achoo", n);
}

void say(string s, int n)
{
    for (int i = 0; i < n; i++) {
        printf("%s\n", s);
    }
}

p.s. 以上code學習自哈佛線上課程

最後, 想紀錄一個學到的東西, 當有人對我說: 去compile你的C source code吧, 實際上包含以下步驟:
preprocessing -> compiling -> assembling -> linking


其中, 我想貼的是上述例子若在assembling階段時的從上階段得來的assembly code(檔名: xxx.s)長得樣子如下:

.text
.file "cough.c"
.globl main
.align 16, 0x90
.type main,@function
main:                                   # @main
.cfi_startproc
# BB#0:
pushq %rbp
.Ltmp0:
.cfi_def_cfa_offset 16
.Ltmp1:
.cfi_offset %rbp, -16
movq %rsp, %rbp
.Ltmp2:
.cfi_def_cfa_register %rbp
movl $3, %edi
callq cough
movl $3, %edi
callq sneeze
xorl %eax, %eax
popq %rbp
retq
.Ltmp3:
.size main, .Ltmp3-main
.cfi_endproc

.globl cough
.align 16, 0x90
.type cough,@function
cough:                                  # @cough
.cfi_startproc
# BB#0:
pushq %rbp
.Ltmp4:
.cfi_def_cfa_offset 16
.Ltmp5:
.cfi_offset %rbp, -16
movq %rsp, %rbp
.Ltmp6:
.cfi_def_cfa_register %rbp
subq $16, %rsp
movabsq $.L.str, %rax
movl %edi, -4(%rbp)
movl -4(%rbp), %esi
movq %rax, %rdi
callq say
addq $16, %rsp
popq %rbp
retq
.Ltmp7:
.size cough, .Ltmp7-cough
.cfi_endproc

.globl sneeze
.align 16, 0x90
.type sneeze,@function
sneeze:                                 # @sneeze
.cfi_startproc
# BB#0:
pushq %rbp
.Ltmp8:
.cfi_def_cfa_offset 16
.Ltmp9:
.cfi_offset %rbp, -16
movq %rsp, %rbp
.Ltmp10:
.cfi_def_cfa_register %rbp
subq $16, %rsp
movabsq $.L.str1, %rax
movl %edi, -4(%rbp)
movl -4(%rbp), %esi
movq %rax, %rdi
callq say
addq $16, %rsp
popq %rbp
retq
.Ltmp11:
.size sneeze, .Ltmp11-sneeze
.cfi_endproc

.globl say
.align 16, 0x90
.type say,@function
say:                                    # @say
.cfi_startproc
# BB#0:
pushq %rbp
.Ltmp12:
.cfi_def_cfa_offset 16
.Ltmp13:
.cfi_offset %rbp, -16
movq %rsp, %rbp
.Ltmp14:
.cfi_def_cfa_register %rbp
subq $32, %rsp
movq %rdi, -8(%rbp)
movl %esi, -12(%rbp)
movl $0, -16(%rbp)
.LBB3_1:                                # =>This Inner Loop Header: Depth=1
movl -16(%rbp), %eax
cmpl -12(%rbp), %eax
jge .LBB3_4
# BB#2:                                 #   in Loop: Header=BB3_1 Depth=1
movabsq $.L.str2, %rdi
movq -8(%rbp), %rsi
movb $0, %al
callq printf
movl %eax, -20(%rbp)         # 4-byte Spill
# BB#3:                                 #   in Loop: Header=BB3_1 Depth=1
movl -16(%rbp), %eax
addl $1, %eax
movl %eax, -16(%rbp)
jmp .LBB3_1
.LBB3_4:
addq $32, %rsp
popq %rbp
retq
.Ltmp15:
.size say, .Ltmp15-say
.cfi_endproc

.type .L.str,@object          # @.str
.section .rodata.str1.1,"aMS",@progbits,1
.L.str:
.asciz "cough"
.size .L.str, 6

.type .L.str1,@object         # @.str1
.L.str1:
.asciz "achoo"
.size .L.str1, 6

.type .L.str2,@object         # @.str2
.L.str2:
.asciz "%s\n"
.size .L.str2, 4


.ident "Ubuntu clang version 3.6.0-2ubuntu1~trusty1 (tags/RELEASE_360/final) (based on LLVM 3.6.0)"
.section ".note.GNU-stack","",@progbits


希望上述的code我不會看懂, 因這是給CPU看懂的instructions, CPU本身有0s和1s的patterns去配對這些instructions。



留言

熱門文章