【发布时间】:2020-10-24 14:13:52
【问题描述】:
您好,我正在努力找出为什么我的二进制搜索实现会出现段错误(我是 NASM 程序集的新手)
抱歉,我知道它不是一个 MVP,但我想不出一种合适的方法来组装它。
%define n [ebp+8]
%define list [ebp+12]
%define low [ebp+16]
%define high [ebp+20] ; Parameters loading from the stack
binary_search:
push ebp
mov ebp, esp
mov ebx, n
mov edi, list
mov ecx, low
mov edx, high
cmp ecx, edx ; if (low > high)
jg .FIRST
mov eax, edx ; Next few lines for mid = low + (high - low)/2
sub eax, ecx
sar eax, 1 ; Will this give an appropriate index? (i.e is it floor division?)
add eax, ecx
lea esi, [edi+eax*4] ;Getting list[mid]
cmp ebx, [esi]; if (n == list[mid])
je .END
jl .SECOND
jg .THIRD
jmp .END
.FIRST:
mov eax, -1 ; return -1
jmp .END
.SECOND:
mov edx, eax ; return middle - 1
dec edx
jmp .CONTINUE
.THIRD:
mov ecx, eax ; low = mid - 1
dec ecx
jmp .CONTINUE
.CONTINUE:
push edx
push ecx
push edi
push esi
push ebx
call binary_search ; recursive call, causing the segfault.
pop ebx
pop esi
pop edi
pop ecx
pop edx
jmp .END
.END:
mov esp, ebp
pop ebp
ret
在注释掉不同的部分后,我确定这肯定与我对导致 seg 错误的 binary_search 的递归调用有关。 (在 .CONTINUE 中找到) 我在搞砸不同意多次递归调用的 binary_search 主体的原因是什么?
二分查找算法:
binary_search(n, list, low, high)
if (low > high)
return -1
mid = low + (high - low) / 2
if (n == list[mid])
return middle;
if (n < list[mid])
high = mid - 1
else
low = mid + 1
return binary_search(n, list, low, high)
我知道这是一个远射,谢谢:)
编辑:它的 32 位模式
【问题讨论】:
-
对于您的评论,算术右移具有向负无穷大舍入的效果,所以是的,地板。你可以尝试一些例子来确认。
-
@liamod:你说得对,部分是对的。但是您将 ebx 作为 n 传递,esi 作为 list 传递,edi 作为 high 传递,而 ecx 作为 low 传递。您还推送和弹出 edx 但不使用该值作为参数。我认为edi不适合这个。不过,我必须检查更多细节才能找到修复方法。
-
您应该放弃
push esi和pop esi。我认为这对于正确的递归调用是必要的,尽管可能不足以修复所有极端情况下的函数。 -
我认为在
.THIRD中你可能应该使用inc ecx而不是dec。 -
谢谢@ecm,主要问题是推送/弹出esi,您能否更详细地解释一下为什么会这样?我会接受这个作为答案。
标签: assembly nasm binary-search