2013-05-06 107 views
0

復位我有以下的彙編代碼:大會EAX寄存器沒有道理

; File: strrev.asm 
; A subroutine called from C programs. 
; Parameters: string A 
; Result: String is reversed and returned. 


    SECTION .text 
    global strrev 
_strrev: nop 
strrev: 
    push ebp 
    mov ebp, esp 

    ; registers ebx,esi, and edi must be saved if used 
    push ebx 
    push edi 

    xor esi, esi  
    xor eax, eax 
    mov ecx, [ebp+8] ; load the start of the array into ecx 
    jecxz end  ; jump if [ecx] is zero 
    mov edi, ecx 

reverseLoop: 
    cmp byte[edi], 0 
    je reverseLoop_1 
    inc  edi 
    inc eax 
    jmp reverseLoop 



reverseLoop_1: 

    mov esi, edi ;move end of array into esi 
    mov edi, ecx ;reset start of array to edi 

reverseLoop_2: 
    mov al, [esi] 
    mov bl, [edi] 
    mov  [esi], bl 
    mov [edi], al 
    inc edi 
    dec esi 
    dec eax 
    jnz reverseLoop_2 

end: 
    pop edi  ; restore registers 
    pop ebx 
    mov esp, ebp ; take down stack frame 
    pop ebp 
    ret 

,直到你開始通過reverseLoop_2循環工作正常。使用gdb,eax被列爲11,它應該是(這是我通過一個單獨的c程序傳入的字符串的長度)。這是展現在調試器:

Breakpoint 2, reverseLoop_2() at strrev.asm:40 
40  mov al, [esi] 
(gdb) display $eax 
1: $eax = 11 

但是,如果我通過程序到下一行一步,它重置爲0。

(gdb) next 
41  mov bl, [edi] 
1: $eax = 0 

我需要EAX,因爲它是要被保留記錄reverseLoop_2需要循環的次數。爲什麼在mov調用之後它重置爲0?

+5

你是在打al al因此eax。請參閱我對您的其他問題的回答;) – scottt 2013-05-06 12:49:38

+0

將註冊更改爲cl工作。但是返回到c程序主體的字符串是「」,或者是一個空字符串。在將控制權返回給c文件之前,是否需要將edi或esi移入ebp寄存器? – user2252004 2013-05-06 13:07:49

+0

您不需要將任何內容存儲到EBP中。聽起來像你沒有得到字符交換循環的初始或終止條件非常正確。比較你的代碼與https://gist.github.com/scottt/5524997 – scottt 2013-05-06 13:10:53

回答

0

我認爲這應該工作。

mov eax, address of your string 

    push esi 
    push edi 

    mov edi, eax 
    mov esi, eax 

    ; find end of string 
    sub ecx, ecx 
    not ecx 
    sub al, al 
    cld 
    repne scasb 

    ; points to the byte after '0x00' 
    dec edi 
    dec edi 

      ; main loop will swap the first with the last byte 
      ; and increase/decrease the pointer until the cross each other 

_loop: 
    cmp esi, edi ; if both pointers meet, we are done 
    jg _done 

    mov al, [edi] 
    mov bl, [esi] 
    mov [esi], al 
    mov [edi], bl 

    inc esi 
    dec edi 

    jmp _loop 

_done: 
    pop edi 
    pop esi 
6

如果您使用eax作爲循環計數器,你不應該寫它在循環中:

reverseLoop_2: 
    mov al, [esi] 

記住aleax最低顯著字節:

enter image description here