Задать вопрос
@DanOK17

Как мне реализовать семеричную систему счисления в ascii символы на nasm?

Не могу реализовать программу, так как не понимаю как перевести из семеричной в десятичную, а из десятичной в ascii код. Очень надеюсь на вашу помощь!!

такое задание
Написать программу преобразования последовательности чисел в
символы. Функцию преобразования оформить в виде подпрограммы.
Числа из таблицы 7.2 (220, 213, 166, 215, 203, 224), согласно варианту, передавать в программу как
аргументы командной строки.

SECTION .data
    errorMsg: db "No arguments", 10
    msgLength: equ $-errorMsg


SECTION .text
    GLOBAL _start


_start:
    pop ecx                 ; Кол-во аргументов заносим в ecx.
    pop eax                 ; Ненужный аргумент (имя программы).
    dec ecx                 ; --ecx.

    cmp ecx, 0              ; Если нет аргументов, то
    je .noArguments         ; переход к метке .noArguments

    .mainLoop:
        pop  eax            ; eax = адрес аргумента.
        call binAsciiToChar ; Строка в код символа.
        call putChar        ; Вывод символа в консоль.
        loop .mainLoop      ; Цикл пока есть аргументы в стеке.
    
    jmp .quit               ; Безусловный переход к метке .quit.

.noArguments:               ; Вывод сообщения об ошибке.
    mov eax, 4
    mov ebx, 1
    mov ecx, errorMsg  
    mov edx, msgLength
    int 80h
    
.quit:
    call quit


; binAsciiToChar
; Из строки, в которой записано
; двоичное число получает десятичное число.
binAsciiToChar:
    push ebx
    push ecx
    push esi
    push edi

    mov esi, eax      ; В esi адрес первого элемента строки.

    call stringLength
    mov  edi, eax     ; В edi длина строки

    xor ebx, ebx      ; Обнуление регистров.
    xor ecx, ecx  
    .nextCharLoop:
        mov bl, [esi] ; Элемент строки по адресу в esi
                      ; записываем в регистр bl.
        sub bl, 48    ; Вычитаем код символа '0'.
        cmp bl, 0     ; Если число не 0 или не 1,  
        jl .break     ; то .break.
        cmp bl, 6
        jg .break
        
        inc esi       ; Следующий символ.
        dec edi       ; Следующая степень.

        mov eax, edi
        call pow7     ; В регистре eax нужная степень.
        mul bl        ; Умножаем 0 или 1 на степень.
        add ecx, eax  ; ecx += (0 или 1)*7^edi.
        cmp edi, 0    ; Цикл пока еще есть символы.
        jne .nextCharLoop
        
.break:
    mov eax, ecx      ; eax = код символа.
    pop edi
    pop esi
    pop ecx
    pop ebx
    ret


; pow7
; Возвращает степени двойки.
; 0 -> 1, 1 -> 7, 2 -> 49, и т.д.
pow2:
    push ebx
    push ecx

    mov ecx, eax
    mov eax, 1
    mov ebx, 7
    .mulLoop:
        cmp ecx, 0
        je .break
        mul ebx
        loop .mulLoop
    
.break:
    pop ecx
    pop ebx
    ret


; stringLength
; Вычисляет длину строки 
; у которой в конце есть
; терминирующий ноль.
stringLength:
    push ebx                 ; Заносим значение рестра ebx в стек
    xor ebx, ebx             ; Обнуляем регистр ebx 
    .nextChar:
        cmp byte[eax+ebx], 0 ; byte[eax+ecx] - Интерпретировать то, что 
                             ; находится по адресу eax+ebx как один байт.
                             ; Если символ '\0'
        je .break            ; то переход к метке .break.
        inc ebx              ; Инкремент ebx.
        jmp .nextChar        ; Безусловный переход к .nextChar.

.break:
    mov eax, ebx             ; Длина строки в регистре eax.
    pop ebx                  ; Возвращаем значение ebx из стека.
    ret


; putChar
; Выводит в консоль один символ,
; ascii код которого записан в
; регистре eax. 
putChar:
    push ebx
    push ecx
    push edx
    
    push eax

    mov eax, 4
    mov ebx, 1
    mov ecx, esp 
    mov edx, 1   
    int 80h
    
    pop eax
    
    pop edx
    pop ecx
    pop ebx
    ret 


; quit
; Завершает программу.
quit:
    mov eax, 1
    mov ebx, 0
    int 80h
  • Вопрос задан
  • 129 просмотров
Подписаться 1 Средний 2 комментария
Пригласить эксперта
Ответы на вопрос 1
trapwalker
@trapwalker
Программист, энтузиаст
А в чем проблема конкретно? Зачем вы привели этот код?
Тут нет даже попытки решить вашу задачу.
Что именно у вас не получается?
Чтобы преобразовать любую систему счисления нужно домножить каждый разряд исходного числа (в исходной системе счисления) на нужную степень основания исходной системы и сложить результаты.
К примеру семиричное число "123" будет состоять из трёх единиц, двух семёрок и одной сорокдевятки: 3+2*7+1*7*7=49+14+3=66. После этх операций вы получите бинарное число, а его уже надо преобразовать в десятичные знаки.
Если готовой функуии для этого у вас нет, то просто действуете обратным способом. Многократно делите число на основание системы счисления (теперь это 10) с остатком. Остатки будут соответствовать десятичным цифрам.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы