从32位转换为8位,反之亦然,在汇编时出现分段故障

问题描述 投票:0回答:1

这可能是我学习x86汇编语言的最后一个障碍。

以下子程序给我一个分段错误:

    ;================================================================= 
    ; 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    
    ;===================================================================

我怀疑从32位寄存器到8位寄存器的数据转换有问题,反之亦然。我对此的概念尚不清楚。

或者,以下部分是否有问题

        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

?

c linux assembly x86 nasm
1个回答
1
投票

cxax是16位寄存器,因此你的push cx ; push cx; push ax在堆栈上推送16位值,总共6个字节。但IsBetweenAandB显然期待32位值,并且最后在esp上添加12(而不是6)。所以你可能想要push ecx等。

此外,您可能希望在使用之前将eaxecx归零。就目前而言,它们最初可能包含垃圾,而您只将有用数据加载到低8位alcl中。因此,当IsBetweenAandB尝试比较完整的32位值时,您将得到错误的结果。或者你想要重写IsBetweenAandB只比较你关心的低字节。

© www.soinside.com 2019 - 2024. All rights reserved.