Как считать число из 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
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д