user366312
user366312

Reputation: 16908

Conversion from 32 bit to 8-bit values and vice-versa in assembly giving segmentation fault

This is probably my final hurdle in learning x86 assembly language.

The following subroutine is giving me a segmentation fault:

    ;================================================================= 
    ; RemCharCodeFromAToB - removes all chars between a and e from str
    ; arguments:
    ;   str - string to be processed
    ;   a   - start
    ;   e   - end
    ; return value:
    ;   n/a 
    ;-------------------------------------------------------------------
    RemCharCodeFromAToB:
        ; standard entry sequence
        push    ebp    ; save the previous value of ebp for the benefi$
        mov     ebp, esp ; copy esp -> ebp so that ebp can be used as a $   

        ; accessing arguments   
                                ; [ebp + 0] = old ebp stack frame
                                ; [ebp + 4] = return address
        mov     edx, [ebp + 8]  ; string address

        while_loop_rcc:
            mov cl, [edx]       ; obtain the address of the 1st character of the string
            cmp cl, 0           ; check the null value  

            je  while_loop_exit_rcc     ; exit if the null-character is reached

            mov al, cl ; save cl
            mov cl, [ebp + 16]      ; end-char
            push cx                 ; push end-char
            mov cl, [ebp + 12]      ; start-char
            push cx                 ; push start-char
            push ax;                ; push ch
            call IsBetweenAandB
            add esp, 12

            cmp eax, 0          ; if(ch is not between 'a' and 'e')

            je inner_loop_exit_rcc

            mov eax, edx    ; copy the current address

            inner_loop_rcc:
                mov cl, [eax+1]
                cmp cl, 0
                je  inner_loop_exit_rcc 

                mov [eax], cl

                inc eax
                jmp inner_loop_rcc
            inner_loop_exit_rcc:

            inc edx             ; increment the address
            jmp while_loop_rcc  ; start the loop again
        while_loop_exit_rcc:

        ; standard exit sequence
        mov     esp, ebp        ; restore esp with ebp
        pop     ebp             ; remove ebp from stack
        ret                     ; return the value of temporary variable    
    ;===================================================================

I am suspecting that there is something wrong with data conversions from 32-bit to 8-bit registers and vice-versa. My concept regarding this is not clear yet.

Or, is there something wrong in the following part

        mov al, cl ; save cl
        mov cl, [ebp + 16]      ; end-char
        push cx                 ; push end-char
        mov cl, [ebp + 12]      ; start-char
        push cx                 ; push start-char
        push ax;                ; push ch
        call IsBetweenAandB
        add esp, 12

?

Upvotes: 0

Views: 900

Answers (1)

Nate Eldredge
Nate Eldredge

Reputation: 58132

cx and ax are 16-bit registers, so your push cx ; push cx; push ax are pushing 16-bit values on the stack, a total of 6 bytes. But IsBetweenAandB is apparently expecting 32-bit values, and you add 12 to esp at the end (instead of 6). So you probably wanted push ecx etc.

Also, you probably want to zero out eax and ecx before using them. As it stands, they probably contain garbage initially, and you only load useful data into the low 8 bits al and cl. Thus when IsBetweenAandB tries to compare the full 32-bit values, you are going to get false results. Or else you want to rewrite IsBetweenAandB to only compare the low bytes that you care about.

Upvotes: 1

Related Questions