Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 检查程序集中输入字符的最干净方法是0到9之间_Assembly_Digits_Micro Optimization_Riscv_Atoi - Fatal编程技术网

Assembly 检查程序集中输入字符的最干净方法是0到9之间

Assembly 检查程序集中输入字符的最干净方法是0到9之间,assembly,digits,micro-optimization,riscv,atoi,Assembly,Digits,Micro Optimization,Riscv,Atoi,问题是在RISC-V中将字符串转换为int 如果存在任何非0~9的字符,请立即返回-1 但我想知道是否有任何方法可以通过使用最小指令来检查它 我的方法是将48和57(对应于ASCII中的0~9)放入临时寄存器, 使用2个分支,首先检查=48 但它使用的指令太多,需要额外的临时寄存器来存储48和57。还有其他有效的方法吗?是的,既然你必须减去'0',那么就这样做,然后进行无符号比较c是的,既然你必须减去'0',那么就这样做,然后进行无符号比较c我很好奇,对于c版本,我能得到什么GCC/clang;

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

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

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

我的方法是将48和57(对应于ASCII中的0~9)放入临时寄存器,
使用2个分支,首先检查=48


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

是的,既然你必须减去
'0'
,那么就这样做,然后进行无符号比较
c是的,既然你必须减去
'0'
,那么就这样做,然后进行无符号比较
c我很好奇,对于c版本,我能得到什么GCC/clang;结果没有我手写的x86 asm好,所以我写了一个答案。看起来RISC-V版本也错过了一些优化。顺便说一句,gcc/clang知道我提到的范围检查技巧;您通常不需要手动实现它。但是将它与
-=“0”
结合起来转换为整数在这里很有用。
// 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;
}