Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ; Читаем массив char-ов cо стандартного потока ввода
- ; в динамическую память.
- ; считывание прекращается в тот момент, когда в потоке ввода встретилось char
- ; со значением 0.
- ; Память выделяем макросом new.
- ;мой основной код для прака
- include console.inc
- ALLONG_SIZE equ 2
- ZERO_CODE equ 48
- SLASH equ 92
- .data
- array_size dd 0
- array_pointer dd 0
- .code
- ;
- ; параметры:
- ; 1. параметр указатель на начало массива.
- ; 2. указатель на размер массива.
- ; возвращаемое значение
- ; 0 - всё хорошо
- ;
- read_array proc
- push ebp
- mov ebp, esp
- ;
- ; зарезервируем место на стеке,
- ; для хранения размера выделенной памяти для массива
- ; выделим 4 байта, в дальнейшем к ним обращаться как
- ; [ebp - 4]
- ;выделяем 4 байта: в младшем байте будет лежать наш char, в остальных трех будут лежать нули
- ;
- sub esp, 20
- ;
- ; В регистре ebx будем сохранять текущий размер считываемого массива.
- ; в edi - будем хранить текущий адрес массива
- ; в esi - считанный элемент массива
- ;
- push ebx
- push esi
- push edi
- mov ebx, 0
- ;
- ; Делаем размер выделенной памяти
- ; равным 0 изначально.
- ; edi указатель на массив проинициализируем 0, чтобы dispose
- ; не вызывать.
- ;
- mov dword ptr [ebp - 4], 0
- mov dword ptr [ebp - 8], 0
- mov dword ptr [ebp - 12], 0
- mov dword ptr [ebp - 16], 0
- mov dword ptr [ebp - 20], 0
- mov edi, 0
- read_elms_loop:
- ;
- ;будем записывать чары в регистр dl
- ;
- outstrln "input elm: "
- inchar dl
- outstr "read elm: "
- outcharln dl
- ;
- ;записываем в esi значение регистра dl, пополненное нулями
- ;
- movzx esi, dl
- cmp esi, ZERO_CODE
- je after_read_elms_loop
- mov ecx, 8
- make_fin_reg:
- shl dword ptr [ebp - 16], 1
- rcl dword ptr [ebp - 20], 1
- loop make_fin_reg
- add dword ptr [ebp - 16], esi
- cmp dword ptr [ebp - 20], '/-:f'
- jne not_slash_pered_fin
- cmp dword ptr [ebp - 12], 1
- je not_fin
- not_slash_pered_fin:
- mov eax, '0-:f'
- and eax, 0ffffffh
- and dword ptr [ebp - 20], 0ffffffh
- cmp dword ptr [ebp - 20], eax
- jne not_fin
- cmp dword ptr [ebp - 16], 'in:-'
- jne not_fin
- jmp after_read_elms_loop
- not_fin:
- ;проверка /
- cmp esi, '/'
- jne not_slash
- cmp dword ptr [ebp - 8], 1
- je not_one_slash
- mov dword ptr [ebp - 8], 1
- mov dword ptr [ebp - 12], 1
- jmp read_elms_loop
- not_one_slash:
- mov dword ptr [ebp - 8], 0
- mov dword ptr [ebp - 12], 0
- not_slash:
- mov dword ptr [ebp - 8], 0
- ; cmp esi, SLASH
- ; outintln esi
- ; jne routine
- ; first_slash:
- ; outstr "input elem: (we got first slash)"
- ; inchar dl
- ; outstr "read elm: "
- ; outcharln dl
- ; movzx esi, dl
- ; cmp esi, ZERO_CODE
- ; je after_read_elms_loop
- ; cmp esi, '\'
- ; je routine
- ; routine:
- ;
- ; проверяем есть ли место куда положить очередной элемент
- ; если нет, то запускаем выделение памяти
- ;
- cmp ebx, [ebp - 4]
- jb mem_enough
- outstrln "allong mem"
- ;
- ; на сколько байт будем удлиннять память.
- ; удлинняем на 2 элемента, каждый по 4 байта.
- ; Для этого пересчитываем размер из элементов в байты.
- ; затем прибавляем то, на сколько увеличиваем размер памяти.
- ; и проверяем на переполнение.
- ; эта часть кода отвечает за ситуацию, когда текущий размер памяти >= выделенному
- ;
- mov eax, 1 ; в eax помещаем 4 - размер одного элемента
- mul ebx ; mul - умножение на eax того, что мы передали результат в EDX:EAX
- ; теперь в eax хранится число байтов, которое выделено под элементы
- add eax, ALLONG_SIZE ; allong_size = 2
- jc process_overflow ;jc - jump carry flag
- ;
- ; Сохраним новый размер в переменную,
- ; где мы храним размер.
- ;
- add dword ptr [ebp - 4], ALLONG_SIZE
- ;
- ; Здесь как параметр макроса передаём размер, который лежит в еах,
- ; сам макрос после работы в регистре eax вернёт
- ; новый указатель на выделенную память.
- ; если памяти нет, то вернётся 0
- ;
- push ebx
- outstr "New memory allocation size: "
- outintln eax
- new eax
- cmp eax, 0
- je process_out_of_mem
- outstr "New pointer to array: "
- outintln eax
- outstr "Old pointer to array: "
- outintln edi
- pop ebx
- ;
- ; переписываем старую память в новую.
- ;
- mov ecx, 0
- copy_elms_loop:
- cmp ecx, ebx
- jae after_copy_elms_loop ; прыжок, если всё перекопировали
- mov dl, [edi + ecx * 1]
- mov [eax + ecx * 1], dl
- inc ecx
- jmp copy_elms_loop
- after_copy_elms_loop:
- ;
- ; меняем указатели и освобождаем старую память.
- ;
- xchg eax, edi
- cmp eax, 0
- je mem_enough
- push ebx
- dispose eax
- pop ebx
- mem_enough:
- ;
- ; Помещаем новый элемент в выделенную память.
- ;
- mov edx, esi
- mov [edi + 1 * ebx], edx
- inc ebx
- jmp read_elms_loop
- after_read_elms_loop:
- outstrln "The program has finished"
- ;
- ; normal finishing
- ;
- ;
- ; возвращаем адрес массива
- ;
- mov esi, [ebp + 8]
- mov [esi], edi
- ;
- ; возвращаем размер массива
- ;
- mov esi, [ebp + 12]
- mov [esi], ebx
- pop edi
- pop esi
- pop ebx
- mov eax, 0
- mov esp, ebp
- pop ebp
- ret 4 + 4
- process_overflow:
- dispose edi ; чистим выделенную память
- pop edi
- pop esi
- pop ebx
- mov eax, 1
- mov esp, ebp
- pop ebp
- ret 4 + 4
- process_out_of_mem:
- dispose edi ; чистим выделенную память
- pop edi
- pop esi
- pop ebx
- mov eax, 2
- mov esp, ebp
- pop ebp
- ret 4 + 4
- read_array endp
- print_array proc
- push ebp
- mov ebp, esp
- push edi
- mov edi, [ebp + 8]
- mov ecx, 0
- loop_print_arr:
- cmp ecx, [ebp + 12]
- jae after_loop_print_arr
- outchar byte ptr [edi + 1 * ecx]
- inc ecx
- jmp loop_print_arr
- after_loop_print_arr:
- pop edi
- pop ebp
- ret 4 + 4
- print_array endp
- start:
- push offset array_size
- push offset array_pointer
- call read_array
- outstr "array read, size: "
- outintln array_size
- push array_size
- push array_pointer
- call print_array
- exit 0
- end start
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement