我正在尝试在NASM中实现以下C代码,然后将其链接到C程序并从那里运行。
我正在尝试实施的代码:
void preKmp(char *x, int m, int kmpNext[]) {
int i, j;
i = 0;
j = kmpNext[0] = -1;
while (i < m) {
while (j > -1 && x[i] != x[j])
j = kmpNext[j];
i++;
j++;
if (x[i] == x[j])
kmpNext[i] = kmpNext[j];
else
kmpNext[i] = j;
}
}
我的NASM尝试与我的评论:
;nasm -f elf32 table.asm -o table.o
segment .bss
kmpNext resd 256
segment .text
global table
table:
push ebp ;save the old base pointer value
mov ebp,esp ;base pointer <- stack pointer
mov eax,[ebp+8] ;function argument, eax = search_string
mov ecx, 0 ;i = 0
mov edx, -1 ;j = -1
mov [kmpNext], edx ;kmpNext[0] = -1
oWhile:
cmp byte [eax + ecx*4], 0 ;end of array control
je finished
iWhile:
cmp edx, -1
jle pass
mov edi,[eax + ecx*4] ;edi = x[i]
mov esi,[eax + edx*4] ;esi = x[j]
cmp edi, esi
je pass
mov edx, [kmpNext +edx*4] ;j = kmpNext[j]
pass:
inc ecx
inc edx
mov edi,[eax + ecx*4] ;edi = x[i]
mov esi,[eax + edx*4] ;esi = x[j]
cmp edi, esi
jne store
mov edi, [kmpNext + edx*4] ;edi = kmpNext[j]
mov [kmpNext + ecx*4], edi ;kmpNext[i] = edi
store:
mov [kmpNext + ecx*4], edx ;kmpNext[i] = j
jmp oWhile
finished:
mov eax, kmpNext;
pop ebp
ret
我在其中调用NASM功能的C代码:
#include <stdio.h>
#include <string.h>
int* table(char *str);
int main(void)
{
char str[256];
int i, n, *pre;
printf("Enter string: ");
scanf("%s" , str) ;
n = strlen(str);
pre = table(str);
for (i = 0; i < n; i++){
printf("%d ", pre[i]);
}
printf("\n");
return 0;
}
所有内容编译并运行正常但输出错误。例如,
对于'cocacola'我应该得到:-1 -1 0 -1 0 1 -1 -1
我得到的地方:-1 0 0 0 0 0 0 0
有人能指出我在NASM代码中的错误吗?
我怀疑问题在于这一行:
mov esi,[eax + ecx * 4]
当我运行调试器时,我看不到esi内容的变化。
答案 0 :(得分:2)
1)主要错误是str
是一个字节数组(8位),但你把它当作一个整数数组(32位)。
2)有两个while循环。 他们两个都需要跳回来重复。
3)store
是else
- 案例。如果if
- 案例合适,它就不能运行。在这种情况下,适当跳转到oWhile
。
这是更正后的功能:
table:
push ebp ;save the old base pointer value
mov ebp,esp ;base pointer <- stack pointer
push edi ; callee saved
push ebx
mov eax,[ebp+8] ;function argument, eax = search_string
mov ecx, 0 ;i = 0
mov edx, -1 ;j = -1
mov [kmpNext], edx ;kmpNext[0] = -1
oWhile:
cmp byte [eax + ecx], 0 ;end of array control
je finished
iWhile:
cmp edx, -1
jle pass
mov bl,[eax + ecx] ; bl = x[i]
mov bh,[eax + edx] ; bh = x[j]
cmp bl, bh
je pass
mov edx, [kmpNext +edx*4] ;j = kmpNext[j]
jmp iWhile
pass:
inc ecx
inc edx
mov bl,[eax + ecx] ; bl = x[i]
mov bh,[eax + edx] ; bh = x[j]
cmp bl, bh
jne store
mov edi, [kmpNext + edx*4] ;edi = kmpNext[j]
mov [kmpNext + ecx*4], edi ;kmpNext[i] = edi
jmp oWhile
store:
mov [kmpNext + ecx*4], edx ;kmpNext[i] = j
jmp oWhile
finished:
mov eax, kmpNext;
pop ebx
pop edi
pop ebp
ret
答案 1 :(得分:1)
routes.MapRoute (
"Default", // Route name
"/{nameofuser}", // URL with parameters
new { controller = "Controller here", action = "Action here" } // Parameter defaults
);
这不等同于oWhile:
cmp byte [eax + ecx*4], 0
。它应该是:
while (i < m)
你回来之前不应该oWhile:
cmp ecx,[ebp+12]
jge finished
;它是一个void函数(虽然没有坏处 - 编译器会忽略返回值)。
此外,您可能需要保存mov eax, [kmpNext]
和edi
以及其他可能的寄存器,否则调用者可能会感到困惑。请查看C编译器手册。