Assembly 如何在ARM部件中将大写字母转换为小写字母?

Assembly 如何在ARM部件中将大写字母转换为小写字母?,assembly,arm,Assembly,Arm,我有以下计划: .data cc: .byte 0x42 .byte 0x4f .byte 0x4e .byte 0x4a .byte 0x4f .byte 0x55 .byte 0x52 .byte 0x00 co: .asciz "au revoir..." .text .global main main: @ impression de la chaine de caractere d'adres

我有以下计划:

 .data
 cc: .byte 0x42
     .byte 0x4f
     .byte 0x4e
     .byte 0x4a
     .byte 0x4f
     .byte 0x55
     .byte 0x52
     .byte 0x00
co: .asciz "au revoir..."

    .text
    .global main
main:

@ impression de la chaine de caractere d'adresse cc
     ldr r1, LD_cc
     bl EcrChaine

@ modification de la chaine d'adresse cc
    @To be completed

@ impression de la chaine modifiee
     ldr r1, LD_co
     bl EcrChaine

fin: B exit  @ terminaison immediate du processus (plus tard on saura faire mieux)

LD_cc: .word cc
LD_ca: .word ca
LD_co: .word co
cc包含大写字母的字符串“BONJOUR”。在“待完成”部分中,我必须获取该字符串,并使用按位OR操作(ORR命令)将其转换为小写字母。我的理解是,由于字符串使用ASCII表,所以我所要做的就是为每个字符添加32。相应的命令是
ORR R1,R1,#32
,但是我正在尝试这样做,当运行程序时,输出为空。我尝试使用在线仿真器查看值的变化,但我可以看到只有第一个字母发生了变化。我必须使用循环吗?有人能帮我吗?

谢谢你的评论。我解决了我的问题。我没有使用循环,因为“这是下周的课程”,但我是这样做的:

首先,我将前4个字符加载到R2中(我不确定是否可以加载更多字符,但我使用的模拟器最多可以存储8个字节。一个字符等于2个字节,因此为4个字符):

R3中的数字32:

MOV R3, 0x20
然后,对于每个字符,我重复了以下指令序列:

ORR r2, r3, r2
LSL r3, r3, #8
我使用LSL将R3(十进制32,十六进制0x20)的值乘以8的2(即乘以256)。因此,对于每个LSL,在我的数字后面加上2个零,我可以在下一个字符上使用ORR指令

完成第一组字符后,我将它们存储在内存中,并加载第二组字符:

STR r2, [r1]
ADD r1, r1, #4
LDR r2, [r1]
我再次将R3初始化为32:

LSR r3, r3, #24
再重复ORR和LSL 3次。我将该组字符存储在第一个字符旁边,然后返回到字符串的开头,并调用在终端上打印字符串的函数:

STR r2, [r1]
SUB r1, r1, #4
bl EcrChaine

这非常有效。然而,结果文件的行数非常大,可以使用循环大大减少,但我暂时没有使用循环,因为“我们在课堂上还没有学到这一点”。

只需添加要转换0x20的单词即可。

是,必须使用一个循环并递增存储当前数组元素地址的寄存器,直到到达元素==0x00(字符串末尾)。此外,如果您对代码有疑问,您应该向我们展示实际代码。是的,
orr
with
0x20
无条件地设置小写位,实现
tolower()
用于已按字母顺序排列的字符。如果不需要循环,则只需重复为下一个字节修改的代码序列。但我使用的模拟器最多可以存储8个字节。ARM是32位ISA。寄存器为32位宽,4字节。如果使用
ldmia
(“pop”是ldmia的特例)或ARMv8
ldp
(加载对)加载到多个寄存器中,则只能加载8个字节。或者使用NEON SIMD寄存器,如d0。具有8字节整数寄存器的ARM的唯一版本是AArch64,它将它们称为x0..x31,而不是r0..r15。这是一个不同的ISA(即使有一些芯片可以在ARM32和AARC64模式之间切换。)也许你在想8个十六进制数字?8个半字节=4个字节。无论如何,如果您想一次处理4个字节,请使用
#0x202020
(您需要在寄存器中使用它)。这比4x
或r2、r3、r2、ror#8
或将每个字节旋转到底部的方法更有效。(有趣的事实:由于重复的位模式,AArch64可以将
0x202020
编码为ORR指令的立即数。)@PeterCordes我实际上尝试过使用
#0x202020
,但我工作的大学服务器在修复后抛出一个
无效常量(2020202),ARM不能将32位立即数编码为32位指令的一部分;只有AArch64具有奇特的位模式编码。您需要将它放入一个包含多条指令的寄存器中,如
ldr r3,=0x202020
,以便让汇编器知道如何进行(例如,从“文字池”中的一个附近常数获得PC相对负载,或者对于低半部和高半部,使用
movw
+
movk
),我们通常一次处理一个字节,而不是试图一次处理多个字节——这使得测试退出条件(例如,给定的长度或空终止)变得容易,并且使正常行为变得容易(例如,字符串不总是字对齐;C字符串“hello”+1==“ello”)。只有在需要极端优化的情况下(或者在已知某些条件的情况下),我们才能一次处理多个字符。
STR r2, [r1]
SUB r1, r1, #4
bl EcrChaine