这可能是我学习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
?
完整的asm代码is here。
C++代码is here。
生成文件is here。
最佳答案
cx
和ax
是16位寄存器,因此push cx ; push cx; push ax
在堆栈上推送16位值,总共6个字节。但是IsBetweenAandB
显然需要32位的值,在结尾处添加12到esp
(而不是6)。所以你可能想要push ecx
等。
另外,在使用它们之前,您可能需要将eax
和ecx
归零。就目前的情况来看,它们最初可能包含垃圾,而您只需将有用的数据加载到低8位al
和cl
中。因此,当IsBetweenAandB
尝试比较完整的32位值时,将得到错误的结果。或者您想重写IsBetweenAandB
以只比较您关心的低字节。
关于c - 从32位值转换为8位值,反之亦然,导致段错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55554890/