2013-04-26 109 views
1

我目前正在學習英特爾x86彙編,並且在嘗試構建循環10次的簡單循環時遇到了問題。它應該在10個循環後停止,但它會一直持續下去。英特爾x86彙編中的循環永遠持續

這是我使用的代碼:

section .data 
    msg  db  "Hello, World!", 0x0a 
    len  equ  $-msg 

    section .text 
    global _start 

    _start: 
      mov  cx, 10 ; loop counter 

      _loop_start: 
        mov  ebx, 0x01 
        mov  ecx, msg 
        mov  edx, len 
        mov  eax, 0x04 
        int  0x80 

        dec  cx 
        cmp  cx, 0 
        jge  _loop_start 

      _done: 
        mov  ebx, 0x00 
        mov  eax, 0x01 
        int  0x80 

之前嘗試寫這樣的代碼,我看着this tutorial做簡單的算術。

予編譯它像這樣:

nasm -f elf64 test.s -o test.o 

和鏈路這樣的:預先

ld -s -o test_exec test.o 

謝謝, Anickyan

回答

4

CX是ECX的低16位部分。你的代碼表明你可能認爲你的循環將運行10次(在循環之前你將cx設置爲10)。但是,你用覆蓋地址爲msg的值覆蓋mov ecx, msg。所以你會從該數字的低16位開始倒數到0。 但是減量甚至沒有效果,因爲在下一次迭代期間,您會用msg的地址再次覆蓋ecx。循環再次開始。這是一個無限循環。 您是否在調試器中檢查軟件?這可以幫助很多。

+0

啊。謝謝!我感覺有什麼東西在覆蓋它,但我不知道cx和ecx是一個(有點) – Anickyan 2013-04-26 07:22:25

+0

@Anickyan [This](http://upload.wikimedia.org/wikipedia/commons/4/41/Table_of_x86_Registers .png)圖像會給你一個'寄存器層次結構'的概念。 – Aaron 2013-04-26 12:07:47

+3

@ JesusPlusPlus11漂亮的圖像,但它缺少一些x86-64寄存器:'sil','dil','bpl','spl'。忽略這些子寄存器與包含其他x86-64通用寄存器不一致。它**完全錯誤**將'sp'和'esp'作爲'rip'的子寄存器! – nrz 2013-04-26 14:33:40

0

如果「覆蓋」問題得到解決,並且如果我們用10的計數器開始減少每個電路的計數器,並且如果我們在計數器的值大於或等於0時分支,則我們變成循環11次。

Alternativly我們還可以使用zeroflag分支(如果zeroflag未設置):

   dec  cl 
       jnz  _loop_start 

的「DEC」的指令已經涉及到標誌寄存器,所以我們並不需要「CMP」 - 指令,如果我們想檢查一個值是否下降到零。

Dirk