如何在ARM汇编(含内联ARM汇编)中获取字符串字符的ASCII值?
ARM内联汇编实现凯撒密码rotN1函数
核心实现思路
- 用ARM寄存器遍历字符串:通过
LDRB指令每次加载单个字符的ASCII值到寄存器 - 终止判断:检测字符是否为
\0(ASCII值0),是则停止遍历 - 小写字母校验:判断字符ASCII值是否在
0x61('a')到0x7A('z')区间内 - 移位加密:符合条件的字符加上偏移量,若超过'z'则减去26实现循环移位
- 原地修改:用
STRB指令将加密后的字符写回原内存地址
完整代码示例
#include <stdio.h> // 仅对小写字母执行凯撒移位,原地修改字符串 void rotN1(char *str, int shift) { // 标准化移位量到0-25区间 shift %= 26; if (shift < 0) shift += 26; __asm__ volatile ( "loop_start:\n" // 加载当前字符ASCII值到r2,同时指针自增 "LDRB r2, [r0], #1\n" // 字符串结束则退出循环 "CMP r2, #0\n" "BEQ loop_end\n" // 小于'a'则跳过 "CMP r2, #0x61\n" "BLT loop_start\n" // 大于'z'则跳过 "CMP r2, #0x7A\n" "BGT loop_start\n" // 执行移位 "ADD r2, r2, %[shift_val]\n" // 超过'z'则循环回字母开头 "CMP r2, #0x7A\n" "BLE store_char\n" "SUB r2, r2, #26\n" "store_char:\n" // 将加密后的字符写回原地址(指针已自增,需偏移-1) "STRB r2, [r0, #-1]\n" "B loop_start\n" "loop_end:\n" // 输入输出约束:str指针既是输入也是输出 : [str_ptr] "+r" (str) // 输入约束:移位量存入寄存器 : [shift_val] "r" (shift) // 告知编译器被修改的资源,避免优化冲突 : "r2", "cc", "memory" ); } int main() { char test_str[] = "Hello World! 123 abc"; printf("原字符串: %s\n", test_str); rotN1(test_str, 3); printf("加密后字符串: %s\n", test_str); return 0; }
关键细节解释
- ASCII值获取:
LDRB r2, [r0], #1指令从r0指向的内存读取1字节(即字符的ASCII值)存入r2,同时r0自动加1,实现字符串指针的移动 - 约束与Clobber:
"+r" (str)声明字符串指针会被汇编修改;"memory"标记告知编译器内存有写入操作,防止优化导致的数据不一致 - 循环逻辑:通过
B loop_start实现循环跳转,遇到终止符\0时通过BEQ loop_end退出循环
内容的提问来源于stack exchange,提问作者Arunima Santhosh Kumr
相关产品推荐
相关产品推荐

