在汇编中从 32 位值转换为 8 位值,反之亦然,给出段错误

标签 c linux assembly x86 nasm

这可能是我学习 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

?

最佳答案

cxax 是 16 位寄存器,所以你的 push cx ;推 cx; push ax 将 16 位值压入堆栈,共 6 个字节。但是 IsBetweenAandB 显然需要 32 位值,并且您在末尾向 esp 添加 12(而不是 6)。所以你可能想要 push ecx 等等。

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

关于在汇编中从 32 位值转换为 8 位值,反之亦然,给出段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55554890/

相关文章:

c - 为什么不能重新分配字符串数组,但是字符串指针可以使用C语言?

C、如何在for循环中存储值,可以不用数组吗?

linux - cmake 找不到 sudo

java - 如何将CLASSPATH环境变量设置为工作目录? (Linux)

linux - bash如何在后台保存multiply进程的返回值?

assembly - 如何阅读汇编操作码引用?

assembly - MIPS - 获取数组值

c - 收到的 IM-MSG 信号消息

c - 哪些 DSP 滤波器算法易于实现?

C在堆栈上为数组分配的空间大小