2

ユーザーが自分の名前を入力するプログラムに取り組んでおり、プログラムはすべての小文字を大文字に変換する必要があります。

%s 形式を使用して文字列を読み取ります:

.text
 ldr r0,=msj
 bl printf
 ldr r0,=format
 ldr r1,string
 bl scanf



.data
.align 2
msj: .asciz "Enter you name:  "
format: .asciz "%s"
string: .asciz ""

各文字に 32 を減算しようとしましたが、文字列が ASCII 形式ではないと思います。

単語全体を大文字に変換する方法はありますか?

4

3 に答える 3

3

これはうまくいくかもしれません。現時点では、ARM の資料は一切持っていません。

; call with address of string in 'R0'.
upperString:
1: ldrb r1,[r0],#1
   tst  r1      ; finished string with null terminator?
   bxeq lr      ; then done and return
   cmp  r1,#'a' ; less than a?
   blo  1b      ; then load next char.
   cmp  r1,#'z' ; greater than z?
   bhi  1b      ; then load next char.

   ; Value to upper case.
   sub  r1,r1,#('a' - 'A') ; subtract 32.
   strb r1,[r0,#-1] ; put it back to memory.
   b    1b      ; next character.

少なくともそれは良い出発点です。これはwallyk のコードに似ていますが、 pascal型の文字列ではなく、 null で終わる文字列を想定している点が異なります。それを呼び出すには、

   ldr r0,=string
   bl  upperString

バリアント

上記は、疑似操作に従って「C」形式の「NULL」(ゼロ値) で終了するASCII文字列の場合です。.asciz文字列エンコーディングのもう 1 つの形式は Pascal 型です。Pascal 文字列は比喩的なint size; char data[size]ものであり、null ターミネータはありません。ループの仕組みはパスカル文字列では異なりますが、コア (xor 0x20またはsub 'a' - 'A') は ASCII エンコーディングでも同じです。

一部の文字列エンコーディングは異なります。固定幅文字列の場合、定数が変更されます。一部の文字列はエスケープ メカニズムを使用し、各「グリフ」または文字は異なる量のデータで表されます。この場合、「ステッピング」アセンブラが変更されます。

最後に、「C」ライブラリでは、これは数字なのか、これは句読点なのかなど、知りたいことがよくあります。これらの場合、その文字のプロパティを持つ各文字のテーブルにインデックスを付けることができます。「大文字」と「小文字」のエンコーディングが連続した範囲でない場合は、このテーブル アプローチを使用することもできます。

バリアントセクションが「カット アンド ペースト」を使用しないプログラマーに役立つことを願っています。

于 2013-05-17T00:31:46.953 に答える
0

これは本質的なアルゴリズムです:

for (int idx = 0;  idx < len;  ++idx)
    if (str [idx] >= 'A'  &&  str [idx] <= 'Z')
         str [idx] += 'a' - 'A';

あなたが持っていないいくつかの部分があります。文字列を 1 文字ずつスキャンします。大文字の検査。小文字/大文字のオフセットを追加します (減算ではありません)。

これは一般に Unicode では機能しないことに注意してください。

于 2013-05-16T23:55:11.553 に答える