You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 22:15:41