アセンブリ言語 strcmpを書いてみた
追記
追記 : 2021/04/14
- コメントにて、rbpを使っていることを指摘いただいたので書き直しました。
- cmpsbの使用については、コメントで書き方を教えて頂きました。
- rdi, rsiが直接インクリメントされるのでDフラグは関係ないようです。
- 結果に関しても、movsxを使うことで、raxに格納できました。
- 参考文献を追記しました。
コード
section .text
global _ft_strcmp
_ft_strcmp:
.loop:
movsx eax, BYTE[rdi]
movsx ecx, BYTE[rsi]
inc rdi
inc rsi
sub eax, ecx
jne .end
test cl, cl
jne .loop
.end:
ret
movsx
返り値のサイズに合わせるため、movsxで拡張して格納し、比較しています。
test
2オペランドの論理積を計算し、結果がゼロならゼロフラグ(ZF)を立てます。
同じclとclを比較しているので、clが0なら0を、1なら1を返します。
テストコード
#include <libc.h>
static void test_strcmp(const char *d, const char *s)
{
printf("%s : %s\n", d, s);
int libasm = ft_strcmp(d, s);
int libc = strcmp(d, s);
printf("libc : %d\n", libc);
printf("libasm : %d\n", libasm);
if (libc == libasm)
printf(GREEN"OK\n"RESET);
else
printf(RED"NG\n"RESET);
}
static void testcase_strcmp()
{
printf("\n--- test strcmp ---\n");
const char *d = "01234";
test_strcmp(d, "01234");
test_strcmp(d, "012341");
test_strcmp(d, " 01234");
test_strcmp("0", d);
test_strcmp("01", d);
test_strcmp("012", d);
test_strcmp("0123", d);
test_strcmp("01234", d);
test_strcmp("", d);
test_strcmp(d, "");
test_strcmp("", "");
}
int main()
{
testcase_strcmp();
return (0);
}
RCXレジスタの使用
文字列をインクリメントさせるための配列の添字として、rcxレジスタを使用した。ループ処理に使われるレジスタです。
RCX
カウンタレジスタの「C」です。繰り返し回数を指定するような命令(シフト、ループ、REPプレフィックス付のストリング型命令)で繰り返し回数の設定に使います。その他は汎用レジスタとして使用できます。Linuxのシステムコールの呼び出しでRCXの内容は保存されません(破壊されます)。
Assembly Programming on x86-64 Linux (04)
参考
レジスタについて
x64 でのソフトウェア規約 | Microsoft Docs
NASM x64 Assembly
Assembly Programming on x86-64 Linux (04)
ステータスフラグについて
条件ジャンプとフラグ
FLAGS register - Wikipedia
X86アセンブラ/x86アーキテクチャ - Wikibooks
movsxについて
Author And Source
この問題について(アセンブリ言語 strcmpを書いてみた), 我々は、より多くの情報をここで見つけました https://qiita.com/keitean/items/261afb9d4f448c61446d著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .