この関数は入力ストリングを取り、それがパリンドロームかどうかをチェックします。しかし、メモリエラーのために破損します。私は数時間それを見てきましたが、問題を把握することはできません。多くの不必要なプッシュがありますが、私はそれで遊んで壊れて、さらに壊れてしまいます。助けていただければ幸いです。アセンブリーでのパリンドロームのチェックMASM
__declspec(naked)
int isPalindrome(char *input_string, int left_index, int right_index)
{
// C code to be converted to x86 assembly
/*
// Input Validation
if (NULL == input_string || left_index < 0 || right_index < 0){
return -1;
}
// Recursion termination condition
if (left_index >= right_index)
return 1;
if (input_string[left_index] == input_string[right_index]){
return isPalindrome(input_string, left_index + 1, right_index - 1);
}
return -1;
*/
__asm{
mov eax, 0
// BEGIN YOUR CODE HERE
push ebp
push edi
mov ebp, esp;
mov ebx, input_string
mov esi, [ebp+12]
mov edi, [ebp+16]
//push edi;
push esi;
push ebx;
// mov some_register, [esp + 8]
mov ebx, input_string
// mov esi, left_index // esi
// mov esi, [esp + 8]
mov edi, right_index // edi
cmp esi, 0;
jl FALSE;
cmp edi, 0
jl FALSE
cmp ebx, 0x00
je FALSE
cmp esi, edi
jge TRUE
mov cl, byte ptr[ebx + esi]
mov dl, byte ptr[ebx + edi]
cmp cl, dl
je RECURSIVE
jmp FALSE
RECURSIVE:
inc esi
dec edi
push eax
push ecx
push edx
push esi
push edi
call isPalindrome
//sub ebp, 8
pop edx
pop ecx
pop edx
jmp END
FALSE:
mov eax, -1
jmp END
TRUE:
mov eax, 1
jmp END
END:
pop ebx;
pop esi;
pop edi;
mov esp, ebp;
pop ebp;
// END YOUR CODE HERE
ret
}
}
(裸)の代わりに__declspecの__stdcall使用してそれを宣言:
はすべてのことが言われて、私は、これはあなたが探しているものだと思いますabba "、第2コール深度のレジスタにどのような値が表示されますか?私がコードを正しく読んでいれば、すでに2番目の深度マッシュにはほとんどすべての引数値が間違っています(返された後、おそらく上位レベルに戻ることはできません)。デバッガ命令で命令を実行したり、机の上にペーパー+ペンを置いたり、レジスタの値に関するメモを書き留めたり、データの期待や定義と比較したりする必要はありません。 – Ped7g
はい、問題は、関数が古い引数で呼び出され、左と右のインデックスが再帰呼び出しで更新されないということです。 –
これは単に真実ではありません。最初に関数を入力すると、 'left_index'はアドレス 'esp + 8'にあり、これは0x0150になります。 2回目の再帰レベルでは 'left_index'も' esp + 8'に戻りますが、評価しても '0x0150'を指していないので、古い引数はありません。あなたは間違った議論をするかもしれませんが、 "古い"はまだメモリの '0x0150'に座っています。だから、 'esp'値に注意を払い始め、スタックの内容を見るためのメモリウィンドウを開きます。 (ちょっとスタックに特化したビューを持っているので、多くのデバッガでは最新のものになっています) – Ped7g