0

私は、特定のプログラムのすべての値を合計するおもちゃの NASM プログラムに取り組んでいます。すべてがどのように機能するかを把握するためにプログラムを作成するときに、NASM をいじっています。

私のプログラムのこれまでのところ、「Works」という一連の出力を配置したので、エラーの場所を絞り込むことができます。

現在、「Work」のプリントアウトが 5 枚あると予想していますが、4 枚しか表示されていません。どうやら、下のコードOutput:は印刷に失敗しているようですが、私の人生ではその理由を理解できません。

segment .data
    ;studentInfo: db 10,'Program by Raphael Stein', 10, '6079652', 10, 10 ;
    ;infoLen: equ $-studentInfo

    NUM_ROWS: equ 5
    NUM_COLUMNS: equ 5
    NUM_ROW_BYTES: equ 10

    ;Default matrix
    matrix: dw  5, 4, 9, 7, 2
        dw  1, 4, 6, 8, 7
        dw  9, 9, 2, 3, 7
        dw  6, 5, 8, 3, 4
        dw  1, 2, 8, 2, 6   
    matrixLen: equ $-matrix

    sum:    db "The sum of the last column is: ", 10

    ;FOR TESTING
    works: db 'Works!', 10
    worksLen: equ $-works

segment .bss
    counter resb 1

segment .text
    global main

main:
;------------------------------------------------------------------------
    mov eax, 4      ; system call 4
    mov ebx, 1      ; standard output 
    mov ecx, works      ; Works!            1
    mov edx, worksLen
    int 0x80
;-------------------------------------------------------------------------
    ;mov CX, NUM_ROWS           ;Works!
    mov ECX, counter
    sub AX, AX
    sub EBX, EBX
    mov ESI, NUM_COLUMNS-1


;------------------------------------------------------------------------
    mov eax, 4      ; system call 4
    mov ebx, 1      ; standard output 
    mov ecx, works      ; Works!            2
    mov edx, worksLen
    int 0x80
;------------------------------------------------------------------------


sum_loop:               
    add EAX, [matrix + EBX + ESI*2]
    add EBX, NUM_ROW_BYTES
    add ECX, 1
    cmp EAX,ECX
    mov esi, eax
    jge Output
    LOOP sum_loop

;------------------------------------------------------------------------
    mov eax, 4      ; system call 4
    mov ebx, 1      ; standard output 
    mov ecx, works      ; Works!            3
    mov edx, worksLen
    int 0x80
;-------------------------------------------------------------------------

Output:
    mov eax, 4  
    mov ebx, 1
    mov ecx, works
    mov edx, worksLen
    int 0x80


;------------------------------------------------------------------------
    mov eax, 4      ; system call 4
    mov ebx, 1      ; standard output 
    mov ecx, works      ; Works!            4
    mov edx, worksLen
    int 0x80
;-------------------------------------------------------------------------

EXIT:
    mov eax, 1
    xor ebx, ebx
    int 0x80
4

1 に答える 1

1

ここにはいくつかの問題があります。順不同:

  • アドホック デバッグ印刷命令シーケンスを別の関数に抽象化する必要があります。それを実践する良い機会になります。そうすることで、コードの重複がなくなり、おそらくいくつかのバグがなくなるでしょう。そのような...
  • sum_loop ラベルの下で、最初の命令が EAX に追加されます。最新の変更 (印刷物のコピー/貼り付けのように見えます) によると、EAX は 4 です。
  • そのため、最初の ADD 命令の後、EAX = 4 + address_of(matrix) + EBX + ESI*2 になります。それは…かなりの量になるでしょう(アドレスが大きくなります)。コードは、「works」文字列のオフセットを含む ECX と比較します。繰り返しますが、これはコピー/貼り付けのため、間違いのように見えます。ECX はおそらく、前のブロックで定義されたカウンターであるはずでした。
  • 「jge Output」命令は、「CMP EAX、ECX」であった前の CMP 命令から結果を取得します。これの正味の効果は、「if (EAX >= ECX) then goto Output」です。ポインターが .data セクションに配置される方法と (場合によっては偶発的な) 数学を組み合わせることで、これが真実であることを暗示しています。これの意味は...
  • Output ラベルの下のコードが実行されています。少なくとも、私の読書はそれを示しています。さまざまなデバッグ出力では、トリガーされているデータは実際には提供されません。出力ラベルののデバッグ印刷ブロックが実行されていないことが予想されます。
  • sum_loop がうっかり短絡してしまったのは幸いだったかもしれません。そうしないと、決して終了しません。x86 LOOP 命令を読み取ります。ECX をデクリメントし、ECX が 0 でない場合は分岐します。反復ごとに ECX に 1 を追加していることに注意してください。つまり、「ECX += 1; if (--ECX != 0) then loop」です。これは決して終了しません。

良いスタートとイニシアチブ。練習を続けてください。

于 2013-03-16T00:06:36.053 に答える