Помогите с ассемблерным кодом (преобразовать строку в int) - PullRequest
2 голосов
/ 01 августа 2011

Я пытаюсь сделать эту программу в сборке.Он должен просто преобразовать строку в десятичную

int main (int argc, char **argv)
{
    int result = 0; 
    char *c = argv[1];  
    while(*c != 0)
    { 
        result *= 10;           
        result += (*c - 48);
        c++;    
    }
return result;
}

, но без получения argv из стека ... поэтому я написал небольшой код в asm, который, я думаю, должен это делать, но он не работает.

Может кто-нибудь указать мне, что я делаю неправильно?Я прокомментировал код, чтобы вы знали, что, я думаю, происходит, пожалуйста, исправьте меня чем-нибудь.

section .bss
        buf resb 8  ; define an array of 8 uninitialised bytes
section .text

global _start
_start:
    mov rax, 3  ; system call number (sys_read)
    xor rbx, rbx    ; file descriptor 0 (stdin)
    mov rcx, buf    ; buffer to store data
    mov rdx, 8  ; Lenght of buffer
    int 0x80

    xor rax,rax ; rax = 0
    mov rbx, buf    ; rbx = &buf
    xor rcx, rcx    

StrToDec:
        mov cl, [rbx]   ; cl = *rbx 
        cmp rcx, 0      ; check for nul THIS IS WRONG
        cmp rcx, 10     ; we have to check for NL ascii code 
        je end          ; if rcx == 0 goto end
        imul rax, 10    ; rax *= 10
        sub rcx, 48     ; rcx -= 48 (48 is acii for '0')
        add rax, rcx    ; rax += rcx
        inc rbx         ; rbx++
        jmp StrToDec

end:
    mov rbx, rax    ; rbx = rax
    mov rax, 1      ; rax = 1
    int 0x80

Когда я запускаю эту программу, набираю, например, 100, а затем набираю echo $?на терминал должно выводиться 100

Спасибо.

Ответы [ 2 ]

2 голосов
/ 01 августа 2011
    mov rcx, [rbx]  ; rcx = *rbx 

Это неправильно, он загружает восемь байтов из буфера.Вы хотите загрузить только 1. Используйте mov cl,[rbx] или movzx ecx, byte [rbx]

0 голосов
/ 02 августа 2011

ИСПРАВЛЕНО:

Я выяснил, что не так с программой = D

Прежде всего вам необходимо проверить значение 10, поэтому

cmp rcx, 0      ; check for nul 

невернопотому что искал новую строку, код ascii не нулевой

cmp rcx, 10      ; check for NL

- это правильно, я не думаю, что это работает, если вы получаете аргументы из стека, при получении аргументов из стека вы должны проверить на 0.

Второе: для чисел больше 255, echo $?даст мне неправильные результаты, но это нормально, потому что echo $?может показывать только числа до 255, поэтому даже если эхо может показывать неправильное число, регистр rbx содержит правильное значение.

Я отладил его, и теперь он работает нормально.

...