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