Arm Assembly Rasperry Pi:将字符串转换为大写

Arm Assembly Rasperry Pi:将字符串转换为大写,assembly,arm,raspberry-pi,Assembly,Arm,Raspberry Pi,我正在编写一个程序,用户在其中输入自己的姓名,该程序应将所有小写字母转换为大写字母: 我正在使用%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数字格

我正在编写一个程序,用户在其中输入自己的姓名,该程序应将所有小写字母转换为大写字母:

我正在使用%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数字格式


有没有办法将整个单词转换成大写?

这是基本算法:

for (int idx = 0;  idx < len;  ++idx)
    if (str [idx] >= 'A'  &&  str [idx] <= 'Z')
         str [idx] += 'a' - 'A';
for(int-idx=0;idx如果(str[idx]>='A'&&str[idx]这是基本算法:

for (int idx = 0;  idx < len;  ++idx)
    if (str [idx] >= 'A'  &&  str [idx] <= 'Z')
         str [idx] += 'a' - 'A';
for(int-idx=0;idx如果(str[idx]>='A'&&str[idx]这可能有用。我现在没有带任何手臂材料

; 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.
至少这是一个很好的起点。这与代码类似,只是我假设了一个以null结尾的字符串,而不是pascal类型的字符串。要调用它

   ldr r0,=string
   bl  upperString

变体 根据
.asciz
pseudo-op,上面是以“C”格式的“NULL”(零值)结尾的字符串。 字符串编码的另一种格式是Pascal类型。 Pascal字符串是一个比喻性的
int size;char data[size]
并且没有空终止符。Pascal字符串的循环机制不同,但ASCII编码的核心(
xor 0x20
sub'A'-'A'
)是相同的

有些是不同的。对于固定宽度的字符串,常量将发生变化。有些字符串使用转义机制,每个“glyph”或字母由不同数量的数据表示。“stepping”汇编程序在这种情况下会发生变化

最后,对于您经常想知道的“C”库,这是一个数字吗?这是标点符号吗?等等。在这种情况下,可以为具有该字符属性的每个字符的表编制索引。如果“大写”和“小写”的编码不是连续的范围,您也可以使用此表方法


希望变体部分对非“剪切粘贴”程序员有用。

这可能有用。我目前没有任何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.
至少这是一个很好的起点。这与代码类似,只是我假设了一个以null结尾的字符串,而不是pascal类型的字符串。要调用它

   ldr r0,=string
   bl  upperString

变体 根据
.asciz
pseudo-op,上面是以“C”格式的“NULL”(零值)结尾的字符串。 字符串编码的另一种格式是Pascal类型。 Pascal字符串是一个比喻性的
int size;char data[size]
并且没有空终止符。Pascal字符串的循环机制不同,但ASCII编码的核心(
xor 0x20
sub'A'-'A'
)是相同的

有些是不同的。对于固定宽度的字符串,常量将发生变化。有些字符串使用转义机制,每个“glyph”或字母由不同数量的数据表示。“stepping”汇编程序在这种情况下会发生变化

最后,对于您经常想知道的“C”库,这是一个数字吗?这是标点符号吗?等等。在这种情况下,可以为具有该字符属性的每个字符的表编制索引。如果“大写”和“小写”的编码不是连续的范围,您也可以使用此表方法


希望变体部分对非“剪切粘贴”程序员有用。

检测字符是否在
'a'
'z'
之间只需一个子
和一个子
cmp
即可进行范围检查。(有关详细信息,请参阅。)

我们可以不修改所有字符,只有原来是小写字母的字符除外。在ARM模式下,我们可以很容易地断言存储(如果条件为false,则充当NOP)。假设CPU能够有效地处理此问题,则不会为没有小写字符的字符串脏化缓存。(@artless noise的答案也是这样的,在到达商店之前跳回到环路的顶部。)

。语法统一
@用R0中字符串的地址调用此函数
大写字符串\u臂\u模式:
从中间开始,或者放上弦:在这里,而不是在这里。
.Lloop:@do{
分包r2、r1、#‘a’
bic r1,#0x20@清除原始文件中的小写位
cmp r2,#'z'-'a'@设置标志
它ls@For Thumb2 compat;在ARM模式下组装为空

strbls r1,[r0,#-1]@strb带LS谓词(检测字符是否在
'a'
'z'
之间的低位或相同无符号只需一个
和一个
cmp
进行范围检查。(有关详细信息,请参阅。)

我们可以不修改所有字符,只有原来是小写字母的字符除外。在ARM模式下,我们可以很容易地断言存储(如果条件为false,则充当NOP)。假设CPU能够有效地处理此问题,则不会为没有小写字符的字符串脏化缓存。(@artless noise的答案也是这样的,在到达商店之前跳回到环路的顶部。)

。语法统一
@用R0中字符串的地址调用此函数
大写字符串\u臂\u模式:
从中间开始,或者放上弦:在这里,而不是在这里。
.Lloop:@do{
分包r2、r1、#‘a’
bic r1,#0x20@清除原始文件中的小写位
cmp r2,#'z'-'a'@设置标志
它ls@For Thumb2 compat;在ARM模式下组装为空

strblsr1,[r0,#-1]@strb with LS predicate(小写或相同的无符号Yes)这正是我所做的,但当我再次打印字符串时,它不会返回反大写字母,它会返回随机字符或只是一个空格str[idx]+='a'-'a';我不认为有汇编指令可以转换为大写,通常当我有一个ascci字符(%c)时,我会减32,但字符串(%s)不会work@PabloEstrada:尝试添加32而不是subtrac