# make this routine available outside this translation unit .globl string_to_integer string_to_integer: # function prologue push %ebp mov %esp, %ebp push %esi # initialize result (%eax) to zero xor %eax, %eax # fetch pointer to the string mov 8(%ebp), %esi # clear high bits of %ecx to be used in addition xor %ecx, %ecx # do the conversion string_to_integer_loop: # fetch a character mov (%esi), %cl # exit loop when hit to NUL character test %cl, %cl jz string_to_integer_loop_end # multiply the result by 10 mov $10, %edx mul %edx # convert the character to number and add it sub $'0', %cl add %ecx, %eax # proceed to next character inc %esi jmp string_to_integer_loop string_to_integer_loop_end: # function epilogue pop %esi leave ret
此GAS风格的代码会将第一个参数给出的十进制字符串(在调用此函数之前已压入堆栈)转换为整数,然后通过返回%eax。之所以%esi被保存,是因为它是被调用者保存寄存器并被使用。
为了使代码简单,不检查溢出/包装和无效字符。
在C语言中,可以像下面这样使用此代码(假定unsigned int和指针的长度为4个字节):
#include <stdio.h> unsigned int string_to_integer(const char* str); int main(void) { const char* testcases[] = { "0", "1", "10", "12345", "1234567890", NULL }; const char** data; for (data = testcases; *data != NULL; data++) { printf("string_to_integer(%s) = %u\n", *data, string_to_integer(*data)); } return 0; }
注意:在某些环境中,string_to_integer必须将汇编代码中的两个更改为_string_to_integer(添加下划线),以使其能够与C代码一起使用。