首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >检查输入字符的最干净的方法是在汇编中0~9之间

检查输入字符的最干净的方法是在汇编中0~9之间
EN

Stack Overflow用户
提问于 2020-10-21 13:00:09
回答 1查看 552关注 0票数 0

问题是在RISC-V中将字符串转换为int

如果存在非0~9字符,立即返回-1

但是我想知道是否有任何方法可以使用最小指令来检查它

我的方法是将48和57 (对应于ASCII中的0~9 )放入temp寄存器,

并使用2个分支,首先检查<=57,然后检查>=48

但是它使用了太多指令,且需要额外的临时寄存器来存储48和57。有没有其他有效的方法?

EN

回答 1

Stack Overflow用户

发布于 2020-10-21 21:31:12

是的,既然你无论如何都要减去'0',那就这样做,然后对c <= 9c < 10进行无符号比较。有关范围检查的技巧,请参阅What is the idea behind ^= 32, that converts lowercase letters to upper and vice versa?

我们可以用C来做这件事,然后看看它是如何编译的,作为紧凑的RISC-V实现的起点。这个C的结构类似于NASM Assembly convert input to integer?中的asm,希望GCC或clang也能使用类似的循环结构。如果您手动翻译它,您可能需要这种循环结构,或者调整它以在有序的RISC-V上进行更好的软件流水线,特别是为了隐藏加载使用延迟。这种循环结构在OoO推测性执行隐藏分支和加载使用延迟的现代x86上非常好用。

代码语言:javascript
复制
// C intentionally written exactly like hand-written asm
// Translate this to asm by hand, including the loop structure.
// or compile it if you want more bloated asm.

unsigned str_to_uint(const unsigned char *p) {
    unsigned dig = *p - '0';
    unsigned total = dig;  // peel first iter, optimize away the  + 0 * 10
    if (total < 10)        // <10 can share a constant with *10
        goto loop_entry;
    else // fall through to the uncommon case of no valid digits
        return 0;

    do {
        total = total*10 + dig;
     loop_entry:            // branch target = loop entry point
        dig = *++p - '0';
    } while(dig < 10);

    return total;
}

我使用taken分支跳过了第一次迭代中的total * 10 + dig,所以我们也可以让它作为我们进入循环的入口,以最小化总代码量。

另一种选择是将另一个循环迭代剥离到循环的顶部。这是GCC和clang在用-O3-O2编译时所选择的。使用-Os,gcc将其反优化为一个循环,其底部为j,中间为btgu break。(Godbolt compiler explorer)。我不知道有什么-march=、RISC-V、arch或tune选项可以尝试。

因此,如果您想要在代码大小和效率之间取得良好的平衡(特别是对于常见的1位或2位数字的情况),您可能应该手动“编译”它。

GCC使用(x<<3) + (x<<1)乘以10;clang使用mul (在循环内部,mulbltu循环分支之间共享一个常量。不幸的是,在循环之外,clang会与9进行比较,比如9 < total,所以它需要这两个常量。( RISC-V是否有bge <=比较?IDK,TODO / edit欢迎讨论这是否是一个遗漏的优化)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64456960

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档