1. ホーム
  2. c

[解決済み] ARMで文字列を扱うには?

2022-02-16 01:58:47

質問

これは宿題のようなものです。正直なところ、C言語プログラムがどのように文字列パラメータをアセンブリレベルに渡すのかがよくわかりません。

私は、関数

StringSearchInString( text, searchString);

とパラメータ

text = "Hallo Alles klar"

searchString = "ll"

ARMがtext, searchStringのパラメータをそれぞれレジスタR0, R1に渡すことは知っていますが、charactesrの場合はどうなんでしょう。もし各文字の長さが8ビットであれば、入力される文字列によってレジスタは容赦なく虐殺される。

ARMのAPCSは引数をワードに変換し、そのうちの最初の4バイトをレジスタに格納し、残りを逆順にスタックにロードすると読んだことがあります。

スッ...何?よくわからないんだけど。文字列 text はR0に格納され、最初の4バイト、"Hall"はR0に格納され、残りは逆順にスタックに格納されるのでしょうか?私の理解は正しいのでしょうか?どのように呼び出すのですか?

TL;DR: C プログラムからアセンブリに文字列の引数を渡し、それを使ってどのように作業/ロード/実行しますか?

ANSWER

この件に関しても解決策を探している人がいるかもしれないので、ここに書いておきます。

Greg Hewgillが言っているように、文字列は文字列へのポインタとして渡されます。したがって、R0の値は文字列へのアドレスとなります。したがって、間接アドレッシングを使って、このような値にアクセスするのです。

StringSearchInString( text, searchString ); // calls the ARM function...

//Going into the ARM function...

LDRB R4, [R0], #1 // Load the first value of R0 into R4 and skip 
                  // ahead one character(8 bits)
                  // Note the "B" in LDR. It indicates that you load ONLY 1 byte!
MOV R0, R4        // Move the value of R4 into R0. This destroys the pointer
                  // Stored in R0! Careful!

そして成功! もしあなたの文字列が私のように "hallo Alles klar" であれば、レジスタR0に0x68がロードされています。これは"h"のASCII値です。これで、文字列を扱うことができるようになります。

解決するには?

簡単に説明すると、C言語では文字列は ポインタ を、どこか別の場所にある文字データに変換します。例えば、R0には 0x01000078 へのポインタと解釈されます。 "Hallo Alles klar" のデータの後に、ヌル文字( 00 バイト)です。これはARMに限ったことではありません。