这可能是我学习 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
?
最佳答案
cx
和 ax
是 16 位寄存器,所以你的 push cx ;推 cx; push ax
将 16 位值压入堆栈,共 6 个字节。但是 IsBetweenAandB
显然需要 32 位值,并且您在末尾向 esp
添加 12(而不是 6)。所以你可能想要 push ecx
等等。
此外,您可能希望在使用它们之前将 eax
和 ecx
清零。就目前而言,它们最初可能包含垃圾,您只将有用的数据加载到低 8 位 al
和 cl
中。因此,当 IsBetweenAandB
尝试比较完整的 32 位值时,您将得到错误的结果。或者您想要重写 IsBetweenAandB
以仅比较您关心的低字节。
关于在汇编中从 32 位值转换为 8 位值,反之亦然,给出段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55554890/