我正在寻找一种将"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 :(得分:3)
没有错误检查,'因为那个超过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;
}
gcc -O2
将其编译为47个字节,但__ctype_b_loc
的外部引用可能超出了您的承受能力......
答案 1 :(得分:1)
我的笔记本电脑上没有汇编程序来检查尺寸,但是随便看起来这应该更短:
; 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
答案 2 :(得分:0)
自己写。请注意,从数字中减去“0”可获得十次幂。所以,你循环数字,每次你把这个值乘以10,从当前字符中减去'0',然后加上它。 Codable在装配中很快就可以了。
答案 3 :(得分:0)
这是另一个没有任何检查。它假定一个空终止字符串。作为奖励,它会检查一个负号。使用Microsoft编译器(cl / O1)需要593个字节。
int myatoi( char* a )
{
int res = 0;
int neg = 0;
if ( *a == '-' )
{
neg = 1;
a++;
}
while ( *a )
{
res = res * 10 + ( *a - '0' );
a++;
}
if ( neg )
res *= -1;
return res;
}
答案 4 :(得分:0)
的atoi(p)的 注册char * p; { 寄存器int n; register int f;
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);
}
答案 5 :(得分:0)
如果使用-Os(优化空间)而不是-O2?
,是否有任何尺寸更小?答案 6 :(得分:0)
您可以尝试将字符串打包成BCD(0x1234),然后使用x87 fbld和第二条指令来获得20世纪80年代的解决方案,但我不确定它会更小,因为我不记得有任何打包指令。< / p>
答案 7 :(得分:0)
你是如何让世界上的可执行文件如此之小?!此代码在使用gcc -Os -m32 -c -o atoi.o atoi.c
编译时生成316字节.o文件,在编译和链接(添加空int main(){}
)时使用gcc -Os -m32 -o atoi atoi.c
生成8488字节可执行文件。这是在Mac OS X Snow Leopard上......
int myatoi(char *s)
{
short retval=0;
for(;*s!=0;s++) retval=retval*10+(*s-'0');
return retval;
}