IA-32 彙編 GAS cdecl 呼叫約定

# 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 的值被儲存,因為它是 callee-save 暫存器並被使用。

不檢查溢位/包裝和無效字元以使程式碼簡單。

在 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 程式碼一起使用。