ここに問題があります:実際にアセンブリ言語でclib関数の一部を再コンパイルしようとしています(これはアセンブリで始めるための学校プロジェクトです)。私が現在取り組んでいる機能はstrcatです。コピー先の文字列がNULLである場合StrCatをx86_64アセンブリで実装する
- 、(RAXに)ソース文字列を返す:私の目標は、単純な、それを維持し、いくつかの次のルールに従うことである瞬間のために 。
- ソース文字列がNULLの場合は、宛先文字列を(raxで)返します。
- 宛先文字列の終わりにソース文字列をコピーし(終端0を含む)、結果を返す(依然としてrax)。ここで
私のコードです:
ft_strcat:
push rbp
mov rbp, rsp ; saving the stack state
push rdi ; seems to work better this way but I don't know why
mov rdi, [rsp + 24] ; destination string
mov rsi, [rsp + 16] ; source string
push rdi ; keeping the adress to return
test rsi, rsi ; in case one of the strings is NULL
je getdest
test rdi, rdi
je getsrc
toend: ; to go to the end of the destination string
cmp byte [rdi], 0x0 ; is it the end?
je cpy ; if so, go to the next part
inc rdi ; else keep going
jmp toend ; loop
cpy: ; to copy the source string to the end of the destination string
mov al, byte[rsi] ; getting the byte to copy
mov byte [rdi], al ; copying it
cmp byte [rsi], 0x0 ; it is the end of the source string?
je getdest ; if so, jump to the end
inc rdi ; else increase counter
inc rsi
jmp cpy ; loop
getdest: ; if source is NULL or copy is done
pop rax
jmp end
getsrc: ; if destination is NULL
mov rax, rsi
end:
pop rdi ; get rdi back
leave
ret ; finally return...
私は(レジスタの変更、レジスタ[直接]に引数を渡すMOVSB、...)異なる方法の膨大な数を試してみましたが、常に同じ結果に到達しました:(我々はまだ文字列にそれを呼び出すことができるかどうか...)文字列の
- とSegfault
- 奇妙な文字
この現在のバージョンでは、宛先部分はそのまま残していますが、末尾に無人文字を追加しています(これは単なる例ですが、文字はしばしば変更される傾向があります)...
私は多分あなた私はインターネット上のすべてを見て、本当に私を助けてくれるものを見つけたことがないので、(少なくとも私は物事を変える場所や私のコードで間違っているかもしれないことのヒントを与える)助けてくれるかもしれません。
私はUbuntuでNasmと仕事をしています(はい、私は知っています))。
Thxは誰にでも答えます。 :)
私はもっと注意を引くために、より記述的なタイトルを提案したいと思います。 –
私はこのようなAPIに対して提案しますが、宛先が無効な場合はソースを返さないでください。ソースが読み込み専用の定数文字列であり、複数の 'strcat'呼び出しを連鎖させ、何らかの理由で最初に' null '( "new"が失敗しました)を受け取れなかった場合、チェーン内の次の 'strcat' 'rax'から' buffer'ポインタを再利用すると、セグメンテーションが解除されます(実際の実装とは無関係のコメントです)。 – Ped7g
ルーチンの本体は大丈夫ですが、 'rdi == null'の場合だけスタックが正しく解放されると思います。 'getdest:'はrdiをraxに最初にポップし、次にrdiに次の値(rbp?)をポップします。そして、すべてが南に行く(ああ待って、それはしない、 '残してあなたを保存します、' rdi'だけバッファーではない)...BTWはデバッガで見やすいはずですが、 'push rbp'を実行して' rsp'を書き留め、 'leave'にブレークポイントを入れると、' rsp'がマッチするはずです。 、 'rsp'はオフにすることができますが、あなたはまだそれを望んでいませんでしたか? – Ped7g