2013-05-06 66 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