0

我正在开发一个玩具 NASM 程序,它将把特定程序中的所有值相加。我现在正在玩 NASM,因为我正在构建我的程序以了解一切是如何工作的。

到目前为止,在我的程序中,我已经放置了一系列显示“有效”的输出,这样我就可以缩小错误所在的范围。

目前我希望看到五份“工作”的打印件,但我只看到四份。显然,下面的代码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 输出”指令从前一个 CMP 指令(即“CMP EAX,ECX”)获取结果。这样做的最终效果是:“如果 (EAX >= ECX) 然后转到输出”。指针在 .data 部分中的排列方式与(有时是偶然的)数学相结合意味着这是真的。这表示...
  • 正在执行输出标签下的代码。至少,我的阅读表明了这一点。您的各种调试打印并没有真正提供任何正在触发的数据。我希望输出标签之前的调试打印块没有被执行。
  • sum_loop 无意中短路可能是一件幸事。否则,它永远不会终止。阅读 x86 LOOP 指令 - 递减 ECX,如果 ECX 不为 0,它会分支。请注意,您通过每次迭代将 1 添加到 ECX。所以,它在做:“ECX += 1; if (--ECX != 0) then loop”。这永远不会终止。

良好的开端和主动性。保持练习。

于 2013-03-16T00:06:36.053 回答