-1

ご存じのように、アセンブリでコーディングする必要があります。または、教授は、適切にコーディングまたはリンクする方法についての情報を提供しませんでした。私たちは自分でそれを学ばなければなりませんでした。明日、私は仕事を提出しなければなりません。目的は、n 番目のフィボナッチ数をコンソールに出力することです。

section .data
    fmt: db "fib=%d",10,0

section .text
extern _printf
global _main, fib

_main:
    mov eax, 10     ; e.g. n=10
    mov ebx, 1      ; we know f_0 and f_1
    sub eax, ebx    ; thats why n--
    push eax        ; push n
    push 0      ; f_0 = 0 
    push 1      ; f_1 = 1

    call fib

    push eax        ; in eax the result is stored
    push fmt
    call _printf

    mov ebx, 0
    mov eax, 1      ; exit(0)
    int 0x80    


fib:
    mov ecx, eax
    pop esi
    calc:
    pop ebx
    pop edx
    add ebx, edx
    mov eax, ebx
    push edx
    push ebx
    sub ecx, 1
    cmp ecx, 0
    jne calc
    push esi
    ret

リンカーに苦労した後、ようやくプログラムをアセンブルしてリンクすることができました。しかし、うまくいきません。毎回セグメンテーション違反が発生します。

編集: 修正されたコード - コンソールにテキストが表示されますが、悲しいことに正しい番号が表示されず、常に「fib = 1」が表示され、再びセグメント障害が表示されます。

4

2 に答える 2

0

組み立ては難しいとは思いませんでしたが、単純でわかりやすいと思いました。先生が正しく教えてくれない場合は、インターネットで情報を検索してみてください。何年も前に私たちのほとんどが始めたときは、それほど多くの情報がなかったので、試行錯誤を繰り返して学習しました。

シンプルに始めて、スタックについて学ぶことをお勧めします。これを実際の例として使用します。

 extern printf
    section .data
    msg:    db "Your sum is %d",10 ,0

    section .text
    global _start

    _start:
        push    20
        push    2
        push    6
        call    AddEm

        push    eax
        push    msg
        call    printf
        add     esp, 4 * 2  ; printf is C calling convention, we have to adjust stack

        mov     ebx, 0
        mov     eax, 1      ; exit(0)
        int     0x80    

    AddEm:
        push    ebp     ; set up a stack frame
        mov     ebp, esp    ; we could just use esp but we won't

        mov     eax, [ebp + 8]  ; 1st param - 6
        add     eax, [ebp + 12] ; 2nd param - 2
        add     eax, [ebp + 16] ; 3rd param - 20

        mov     esp, ebp    ; restore the stack
        pop     ebp
        ret     4 * 3       ; passed 3 params, clean up stack

そして、これが私がどのように組み立て、リンクし、出力したかです。

スクリーンショット

于 2012-05-30T03:12:33.767 に答える
0

あなたが持っている

push 0      ; f_0 = 0 
push 1      ; f_1 = 1

call fib

それから

fib:
    mov ecx, eax
    calc:
    pop ebx
    pop edx

それはできません - call 命令は戻りアドレスをスタックにプッシュし、それが fib で最初に取り出されることになります。

于 2012-05-29T22:41:14.573 に答える