装配EAX寄存器无故重置

时间:2013-05-06 12:48:25

标签: c assembly

我有以下汇编代码:

; 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

2 个答案:

答案 0 :(得分:6)

如果您使用eax作为循环计数器,则不应在循环内写入:

reverseLoop_2:
  mov al, [esi]

请记住aleax中最不重要的字节:

enter image description here

答案 1 :(得分: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