download

kono先生のディレクトリをcloneする

$rsync -avzP yomitan:../../../teacher/kono/public_html/compiler/compiler-examples ./
$ make clean
$ rm s-calc
$ rm s-intel
$ make s-calc
$ make s-intel

s-intel

この s-intel はkono先生が作ったx86系アーキテクチャのAssemblerをインタプリタのように出力する。 例えば1+3を入力すると

#APP
        .file   "s-calc.c"
.text
        .align 2
.globl main
main:
        pushl %ebp
        movl %esp,%ebp
        subl $1028,%esp
1+3
##### 1+3
        movl $3,%eax
        pushl %eax
        movl $1,%eax
        popl %ebx
        addl %ebx,%eax
        call _print
## 1+3

などと出力される。

このkono先生の結果と自分で作ったアセンブラの結果を比較しながら読んでいこう。

asmb

1からアセンブラを書いてもいいが、荷が重い。 そこで適当なCを作成して、コンパイルし、これを使っていく

#include <stdio.h>

int main(void){

    int d = 7;

    printf("%d\n",d);
    return 0;
}

これをアセンブラで出力する

$ clang -O0 -S hoge.c

そうすると適当な雛形ファイルが生成される.

    .section    __TEXT,__text,regular,pure_instructions
    .macosx_version_min 10, 12
    .globl    _main
    .align    4, 0x90
_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
    subq    $16, %rsp
    leaq    L_.str(%rip), %rdi
    movl    $0, -4(%rbp)
    movl    $7, -8(%rbp)
    movl    -8(%rbp), %esi
    movb    $0, %al
    callq    _printf
    xorl    %esi, %esi
    movl    %eax, -12(%rbp)         ## 4-byte Spill
    movl    %esi, %eax
    addq    $16, %rsp
    popq    %rbp
    retq
    .cfi_endproc

    .section    __TEXT,__cstring,cstring_literals
L_.str:                                 ## @.str
    .asciz    "%d\n"


.subsections_via_symbols
Ltmp2:
    .cfi_def_cfa_register %rbp
    subq    $16, %rsp
    leaq    L_.str(%rip), %rdi

Ltmp2のこの前後はテンプレである。

    movl    $0, -4(%rbp)
    movl    $7, -8(%rbp)
    movl    -8(%rbp), %esi
    movb    $0, %al
    callq    _printf

一方このmovlの命令は7の出力に関わっているのみである。 ここから%alに対して値を渡せば,print出来るとかんがえられる。 よってこの部分を修正していこう。

tree

実際にアセンブラにする前に、構文木を作る必要がある。 例えば 3+4*2

        | +|
     |        |
     v        v
    | 3|     | * |
           |       |
            v     v 
           |4|    | 2|

このようになる。 演算子と数値が同じ深さに並んでいる場合、それはスタックを利用して演算する必要がある事示している。 基本は深く、右からやるなどが良いかもしれない。

ex1

例えば3-(4-2)は次のようになる。 ここで addq などの向きを気をつける。 また64bitでの演算にするか、適切に32bitで演算できるようにする必要性がある。

命令についてはこのサイトがわかりやすいだろう。

    .section    __TEXT,__text,regular,pure_instructions
    .macosx_version_min 10, 12
    .globl    _main
    .align    4, 0x90
_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
    subq    $16, %rsp
    leaq    L_.str(%rip), %rdi
    movq $3,%rax     
    pushq %rax
    movq $4,%rax
    movq $2,%rbx
    subq %rbx,%rax     # 4-2     ...sub S,D  D<- D - S
    popq %rbx
    subq %rax,%rbx    # 3- (4-2)
    movq %rbx,%rsi
    movb    $0, %al
    callq    _printf
    xorl    %esi, %esi
    movl    %eax, -12(%rbp)         ## 4-byte Spill
    movl    %esi, %eax
    addq    $16, %rsp
    popq    %rbp
    retq
    .cfi_endproc

    .section    __TEXT,__cstring,cstring_literals
L_.str:                                 ## @.str
    .asciz    "%d\n"


.subsections_via_symbols

ex2

    .section    __TEXT,__text,regular,pure_instructions
    .macosx_version_min 10, 12
    .globl    _main
    .align    4, 0x90
_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
    subq    $16, %rsp
    leaq    L_.str(%rip), %rdi
    movq     $0,%rax   # 0
    pushq     %rax     # stack [0]
    movq     $1,%rax  # 1
    movq     $3,%rbx  #3
    movq    $2,%rcx  #2
    subq    %rcx,%rbx  # 3-2
    addq    %rbx,%rax    # 1+ (3-2)
    pushq   %rax        stack[0,(1+(3-2))]
    movq    $0,%rax
    movq       $1,%rbx
    movq    $2,%rcx
    movq     $3,%rdx
    subq    %rdx,%rcx    # 2-3
    addq    %rcx,%rbx    # 1+(2-3)
    addq    %rbx,%rax    # 0+(1+(2-3))
    popq    %rbx        # %rbx <- 1+(3-2)
    subq    %rax,%rbx    # 1+(3-2) - (0+(1+(2-3)))
    popq    %rax        #  %rax <- 0
    addq    %rbx,%rax    #0+(1+(3-2))-(0+(1+(2-3)))
    movq    %rax,%rsi
    movb    $0, %al
    callq    _printf
    xorl    %esi, %esi
    movl    %eax, -12(%rbp)         ## 4-byte Spill
    movl    %esi, %eax
    addq    $16, %rsp
    popq    %rbp
    retq
    .cfi_endproc

    .section    __TEXT,__cstring,cstring_literals
L_.str:                                 ## @.str
    .asciz    "%d\n"


.subsections_via_symbols

results matching ""

    No results matching ""