Itoa程序集的实现,div操作会导致段错误?

时间:2019-01-26 17:18:29

标签: linux assembly nasm x86-64

所以我试图实现itoa,它将一个int转换为一个字符串。 到目前为止,如果我不在.loop节中循环并坚持少量,则该实现将正常工作。一旦循环,我的程序就会出现段错误。

代码如下:

section .data
    buffer  times 11 db 0

section .text
    global  ft_itoa
    extern  ft_strrevd
    extern  malloc

ft_itoa:
    mov     rcx, 1                      ;initialize our counter at 1 for the terminating null byte
    mov     rax, rdi                    ;move number in RAX for DIV instruction
    push    rbx                         ;save RBX
    mov     bl, 10

.check_negative:
    and     edi, 0xf0000000
    mov     rdi, buffer
    jz      .loop                       ;number is positive, proceed to main loop
    not     rax                         ;else
    inc     rax                         ;compute absolute value with binary complement
    mov     r9, 1                       ;set neg flag

.loop:
    cmp     rax, 0
    jz      .check_neg_flag
    div     bl
    add     ah, 48                      ;convert int to char
    mov     byte[rdi + rcx - 1], ah     ;copy char in buffer
    sub     ah, 48
    inc     rcx
    jmp     .loop                       ;commenting this line prevents crash

.check_neg_flag:
    cmp     r9, 1
    jne     .dup
    mov     byte[rdi + rcx - 1], '-'
    inc     rcx

.dup:
    mov     byte[rdi + rcx - 1], 0
    call    ft_strrevd                  ;copy buffer string in memory and return pointer

.end:
    pop     rbx                         ;restore RBX
    ret

最有可能是由div引起的,但是我在理解它的工作方式时遇到了麻烦。 如果有人能指出我的解决方案,将不胜感激。

1 个答案:

答案 0 :(得分:0)

因此,要解决此问题,我必须使用div ebx代替div bl,并在每个div之前使用xor edx,edx。

这是一个有效的版本:

section .data
    buffer  times 11 db 0

    nega db "neg",0
    posi db "pos",0

section .text
    global  ft_itoa
    extern  ft_strdup
    extern  malloc

ft_itoa:
    xor     rcx, rcx                    ;initialize counter
    xor     r9, r9                      ;set neg flag to 0
    mov     eax, edi                    ;move number in RAX for DIV instruction
    push    rbx                         ;save RBX
    mov     ebx, 10

.check_negative:
    and     edi, 0x80000000
    mov     rdi, buffer
    jz      .divide                     ;number is positive, proceed to main loop
    not     eax                         ;else
    inc     eax                         ;compute absolute value with binary complement
    inc     r9                          ;set neg flag

.divide:
    xor     edx, edx
    div     ebx
    add     edx, 48                     ;convert int to char
    push    rdx
    inc     rcx
    cmp     eax, 0
    jnz     .divide

.check_neg_flag:
    cmp     r9, 1
    jne     .buff_string
    mov     byte[rdi], '-'

.buff_string:
    pop     rdx
    mov     byte[rdi + r9], dl
    dec     rcx
    inc     r9
    cmp     rcx, 0
    jnz     .buff_string

.dup:
    mov     byte[rdi + r9], 0
    call    ft_strdup                   ;copy buffer string in memory and return pointer
    pop     rbx                         ;restore RBX
    ret