Как считать число из stdin для дальнейшего использования - Assembler

Узнай цену своей работы

Формулировка задачи:

Использую NASM под OCUNIX

Решение задачи: «Как считать число из stdin для дальнейшего использования»

textual
Листинг программы
%define SUCCESS 0 ; возвращаемое значение функции в случаи успеха
%define MIN_MAX_NUMBER 2 ; мин.ввод.число
%define MAX_MAX_NUMBER 4294967294 ; 2^32 макс.ввод. число
 
global _start ; делаем глобальной точку старта программы
 
;определение функции из библиотеки Си
extern _printf  
extern _scanf
extern _malloc
extern _free
 
;определение доп.функций
     
     ; ФУНКЦИИ
; Результат записывается в EAX, статус - в EDX.
; В случае успеха EDX содержит значение SUCCESS (0),
; инчае - адрес сообщения об ошибке.
;
;
 
; Ввести максимальное число
; Результат: EAX - максимальное число
input_max_number:   
    ;создать стек-фрейм,
    ;4 байта для локальных переменных
    enter 4, 1
 
    ;показываем подпись
    push str_max_number_label ;см. SECTION .data
    call _printf
    add esp, 4
 
    ;вызываем scanf
    mov eax, ebp
    sub eax, 4
    
    push eax
    push str_max_number_input_format ;см. SECTION .data
    call _scanf
    add esp, 8
    
    mov eax, [ebp-4]
 
    ;проверка
    cmp eax, MIN_MAX_NUMBER
    jb .number_too_little
    cmp eax, MAX_MAX_NUMBER
    ja .number_too_big
    jmp .success
 
    ;выход
    .number_too_little:
        mov edx, str_error_max_num_too_little ;см. SECTION .data
        jmp .return 
        
    .number_too_big:
        mov edx, str_error_max_num_too_big ;см. SECTION .data
        jmp .return 
 
    .success:
        push eax
        push str_max_number_output_format ;см. SECTION .data
        call _printf
        add esp, 4
        pop eax
        mov edx, SUCCESS
    
    .return:
        leave
        ret
 
 
; Выделить память для массива флагов
; Аргумент: EAX - максимальное число
; Результат: EAX - указатель на память
allocate_flags_memory:
    enter 8, 1
 
    ;выделить EAX+1 байт
    inc eax
    mov [ebp-4], eax
    
    push eax
    call _malloc
    add esp, 4
    
    ;проверка
    cmp eax, 0
    je .fail
    mov [ebp-8], eax
    
    ;инициализация
    mov byte [eax], 0
    
    cld
    mov edi, eax
    inc edi
    mov edx, [ebp-4]
    add edx, eax
    
    mov al, 1
    .write_true:
        stosb
        cmp edi, edx
        jb .write_true
    
    ;выход
    mov eax, [ebp-8]
    jmp .success
    
    .fail:
        mov edx, str_error_malloc_failed ;см. string_constants.asm
        jmp .return
    
    .success:
        mov edx, SUCCESS
            
    .return:
        leave
        ret
 
; Освободить память от массива флагов
; Аргумент: EAX - указатель на память
free_flags_memory:
    enter 0, 1
    
    push eax
    call _free
    add esp, 4
    
    leave
    ret
    
    
;Найти простые числа с помощью решета Эратосфена
;Аргументы: EAX - указатель на массив флагов, EBX - максимальное число  
find_primes_with_eratosthenes_sieve:
    enter 8, 1
    mov [ebp-4], eax
        
    add eax, ebx
    inc eax
    mov [ebp-8], eax
    
    ;вычеркиваем составные числа
    cld
    mov edx, 2 ;p = 2
    mov ecx, 2 ;множитель с = 2
    .strike_out_cycle:
        ;x = c*p
        mov eax, edx
        push edx
        mul ecx
        pop edx
        
        cmp eax, ebx
        jbe .strike_out_number
        jmp .increase_p
        
        .strike_out_number:
            mov edi, [ebp-4]
            add edi, eax
            mov byte [edi], 0
            inc ecx ;c = c + 1
            jmp .strike_out_cycle
            
        .increase_p:
            mov esi, [ebp-4]
            add esi, edx
            inc esi
            
            mov ecx, edx
            inc ecx
            .check_current_number:
                mov eax, ecx
                mul eax
                cmp eax, ebx
                ja .return
            
                lodsb
                inc ecx
                cmp al, 0
                jne .new_p_found
                jmp .check_current_number
            
                .new_p_found:
                    mov edx, ecx
                    dec edx
                    mov ecx, 2
                    jmp .strike_out_cycle           
    
    .return:
        leave
        ret
        
 
; Вывести простые числа
; Параметры: EAX - указатель на массив флагов, EBX - максимальное число
print_primes:
    enter 12, 1
    mov [ebp-4], eax
    mov [ebp-8], ebx
    
    push str_print_primes_label
    call _printf
    add esp, 4
    
    cld
    mov esi, [ebp-4]
    mov edx, esi
    add edx, [ebp-8]
    inc edx
    
    mov [ebp-12], edx
    mov ecx, 0
    .print_cycle:
        lodsb
        cmp al, 0
        jne .print
        jmp .check_finish
        .print:
            push esi
            push ecx
            push str_prime ;см. string_constants.asm
            call _printf
            add esp, 4
            pop ecx
            pop esi
            mov edx, [ebp-12]
        .check_finish:
            inc ecx
            cmp esi, edx
            jb .print_cycle
            
    push str_cr_lf
    call _printf
    add esp, 4
            
    leave
    ret
 ;;
    
;;НАЧАЛО ОСНОВНОГО КОДА 
    
SECTION .text
_start: ; точка старта программы
    enter 0, 0 ; 
    
    ;ввод максимального числа
    call input_max_number ; функция в случаи успеха кладет в edx 0, а результат кладет в eax
    cmp edx, SUCCESS ; сравниваем
    jne .custom_exit 
    mov [max_number], eax
    
    ;выделяем память для массива флагов
    mov eax, [max_number]
    call allocate_flags_memory
    cmp edx, SUCCESS
    jne .custom_exit
    mov [primes_pointer], eax
    
    ;отсеять составные числа
    mov eax, [primes_pointer]
    mov ebx, [max_number]
    call find_primes_with_eratosthenes_sieve
    
    ;вывести числа
    mov eax, [primes_pointer]
    mov ebx, [max_number]
    call print_primes
    
    ;освободить память от массива флагов
    mov eax, [primes_pointer]
    call free_flags_memory
    
   ;выход
    .success:
        push str_exit_success
        call _printf
        jmp .return
            
    .custom_exit:
        push edx
        call _printf
        
    .return:
        mov eax, SUCCESS
        leave
        ret
        
SECTION .data
    max_number: dd 0
    primes_pointer: dd 0
    
    ;определение строковых переменных
    
    ;подписи ввода-вывода, форматы
str_max_number_label: db "Input number: ", 0
str_max_number_input_format: db "%u", 0
str_max_number_output_format: db "Using number %u", 0xD, 0xA, 0
 
str_print_primes_label: db "Primes:", 0xD, 0xA, 0
str_prime: db "%u", 0x9, 0
str_cr_lf: db 0xD, 0xA, 0
    
;сообщения выхода
str_exit_success: db "Success!", 0xD, 0xA, 0
str_error_max_num_too_little: db "Max number is too little!", 0xD, 0xA, 0
str_error_max_num_too_big: db "Max number is too big!", 0xD, 0xA, 0
str_error_malloc_failed: db "Can't allocate memory!", 0xD, 0xA, 0

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

10   голосов , оценка 4.2 из 5
Похожие ответы