Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.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
C 将字符串转换为整数的最小方法(反之亦然)_C_Optimization_Assembly - Fatal编程技术网

C 将字符串转换为整数的最小方法(反之亦然)

C 将字符串转换为整数的最小方法(反之亦然),c,optimization,assembly,C,Optimization,Assembly,我正在寻找一种非常小的方法,将像“123”这样的字符串转换成像123这样的整数,反之亦然 我将在一个独立的环境中工作。这不是一个过早的优化。我正在创建必须适合512字节的代码,所以每个字节实际上都有计数。我将同时使用x86汇编(16位)和C代码(因为这很容易转换) 它不需要做任何健康检查或任何事情 我以为我看到过一个非常小的C实现是递归实现的,但我似乎找不到任何用于大小优化的东西 那么,有人能找到我(或创建)一个非常小的atoi/itoa实现吗?(但它只需要使用基数10) 编辑:(答案)(再次编

我正在寻找一种非常小的方法,将像
“123”
这样的字符串转换成像
123
这样的整数,反之亦然

我将在一个独立的环境中工作。这不是一个过早的优化。我正在创建必须适合512字节的代码,所以每个字节实际上都有计数。我将同时使用x86汇编(16位)和C代码(因为这很容易转换)

它不需要做任何健康检查或任何事情

我以为我看到过一个非常小的C实现是递归实现的,但我似乎找不到任何用于大小优化的东西

那么,有人能找到我(或创建)一个非常小的atoi/itoa实现吗?(但它只需要使用基数10)

编辑:(答案)(再次编辑,因为第一个代码实际上是错误的) 如果其他人遇到这个问题,这就是我最终创建的代码。它可以容纳21个字节

;ds:bx is the input string. ax is the returned integer
_strtoint:
    xor ax,ax
    .loop1:
        imul ax, 10 ;ax serves as our temp var
        mov cl,[bx]
        mov ch,0
        add ax,cx
        sub ax,'0'
        inc bx
        cmp byte [bx],0
    jnz .loop1
ret
好的,我发誓! 支持负数的42字节版本。。所以如果有人想用这些,他们可以


;ds:bx is the input string. ax is the returned integer
_strtoint:
    cmp byte [bx],'-'
    je .negate
    ;rewrite to negate DX(just throw it away)
    mov byte [.rewrite+1],0xDA
    jmp .continue
    .negate:
    mov byte [.rewrite+1],0xD8
    inc bx
    .continue
    xor ax,ax
    .loop1:
        imul ax, 10 ;ax serves as our temp var
        mov dl,[bx]
        mov dh,0
        add ax,dx
        sub ax,'0'
        inc bx
        cmp byte [bx],0
    jnz .loop1
    ;popa
    .rewrite:
    neg ax ;this instruction gets rewritten to conditionally negate ax or dx
ret

你自己写吧。请注意,从一个数字中减去“0”得到十的幂。所以,你把这些数字循环下来,每次你把这个值乘以10,从当前字符中减去“0”,然后加上它。可在无时间限制的情况下在汇编中进行编码。

无错误检查,因为这是针对拥有512B以上数据的wussies的:

#include <ctype.h>
// alternative:
// #define isdigit(C) ((C) >= '0' && (C) <= '9')

unsigned long myatol(const char *s) {
  unsigned long n = 0;
  while (isdigit(*s)) n = 10 * n + *s++ - '0';
  return n;
}
#包括
//备选方案:

//#define isdigit(C)((C)>='0'&&&(C),这里是另一个未经任何检查的字符串。它假设以null结尾的字符串。作为奖励,它检查负号。使用Microsoft编译器(cl/O1)需要593字节

原子能机构(p) 寄存器char*p; { 寄存器int n; 寄存器INTF

n = 0;
f = 0;
for(;;p++) {
    switch(*p) {
    case ' ':
    case '\t':
        continue;
    case '-':
        f++;
    case '+':
        p++;
    }
    break;
}
while(*p >= '0' && *p <= '9')
    n = n*10 + *p++ - '0';
return(f? -n: n);
n=0;
f=0;
对于(;;p++){
开关(*p){
案例“”:
案例'\t':
继续;
案例'-':
f++;
格“+”:
p++;
}
打破
}

如果使用-Os(优化空间)而不是-O2,那么(*p>='0'&&&&*p是否有任何尺寸更小?

您可以尝试将字符串打包到BCD(0x1234)中然后在80年代的解决方案中使用x87 fbld和fist指令,但我不确定它是否会更小,因为我不记得有任何打包指令。

你们这些人到底是怎么把可执行文件弄得这么小的?!这段代码在使用
gcc-Os-m32-c-o atoi.o atoi.c
a编译时会生成一个316字节的.o文件编译并链接(添加了一个空的
int main(){}
gcc-Os-m32-o atoi atoi.c
)时,将生成一个8488字节的可执行文件

int myatoi(char *s)
{
 short retval=0;
 for(;*s!=0;s++) retval=retval*10+(*s-'0');
 return retval;
}

我的笔记本电脑上没有装配工来检查尺寸,但随便说一下,看起来应该更短一些:

; input: zero-terminated string in DS:SI
; result: AX
atoi proc
        xor cx, cx
        mov ax, '0'
    @@:
        imul cx, 10
        sub al, '0'
        add cx, ax
        lodsb
        jnz @b
        xchg ax, cx
        ret
atoi endp

您要转换的数字的大小是否有任何限制?32位还是64位?有符号还是无符号?处理有符号的数字是一种奖励,但我只选择16位数字嗯,哦,有人正在编写引导程序:)这是一个竞赛。一个引导扇区可以容纳多少内容。我正在寻找一个半生不熟的Forth解释程序,我还以为它是为了4k或256b演示:如果没有错误检查,为什么要检查每个字符都是一个数字?只需循环,直到你看到一个\0。我认为你不需要将C源代码放入512字节。噢..整洁忘记了
lods
指令..我必须在下班后检查这个问题…调试符号或ELF头是很常见的事情…您只需尝试使用交叉编译器在独立环境中创建平面二进制文件…或者只需将其反汇编并计算字节数。。。
; input: zero-terminated string in DS:SI
; result: AX
atoi proc
        xor cx, cx
        mov ax, '0'
    @@:
        imul cx, 10
        sub al, '0'
        add cx, ax
        lodsb
        jnz @b
        xchg ax, cx
        ret
atoi endp