Другие языки программирования и технологии
Цикл обхода массива в ассемблере
Нужно, пока что, найти последний четный элемент в массиве. Учу ассемблер недавно, поэтому не знаю как организовать выход из цикла. Не будет ли инкрементироваться переменная номера элемента массива, после того, как массив закончится? Не находил функцию по нахождению длины массива в ассемблере, а делать цикл с фиксированным количеством выполнений для массива с точным количеством элементов не хочется. Надеюсь, что смог объяснить внятно. Пишу под Windows в MASM.
> не знаю как организовать выход из цикла
Если нужно просматривать все элементы массива (а в вашем случае именно это и требуется) , то используют инструкцию loop.
> Не будет ли инкрементироваться переменная номера элемента массива, после того, как массив закончится
Если вы не вставите команду инкремента после выхода из цикла, то не будет.
> делать цикл с фиксированным количеством выполнений для массива с точным количеством элементов не хочется
Вот пример программы (MASM, Windows x86), в которой кол-во элементов массива не фиксировано, а при каждом запуске программы задаётся случайно. Элементы массива тоже генерируются случайно. Память под массив выделяется автоматически, в соответствии с размером массива.
.586
.model flat, C
option casemap :none
include windows.inc
includelib kernel.lib
includelib msvcrt.lib
VirtualAlloc proto stdcall :dword, :dword, :dword, :dword
VirtualFree proto stdcall :dword, :dword, :dword
printf proto :dword, :vararg
_getch proto
_exit proto :dword
.data
ArrayItemFormat db "%8d", 0
Message db "Дан массив [1 .. %d]:", 13, 10, 0
Result db 13, 10, 10, "Последний чётный элемент массива [%d] = %d", 0
NoEven db 13, 10, 10, "В массиве нет чётных элементов", 0
Prompt db 13, 10, 10, "Для завершения работы нажмите любую клавишу... ", 0
.data?
Seed dd ?
ArraySize dd ?
Array dd ?
.code
Random proc uses edx, Range :dword
mov eax, Seed
mov edx, 08088405h
mul edx
inc eax
mov Seed, eax
mul Range
mov eax, edx
ret
Random endp
N168755120:
rdtsc
mov Seed, eax
invoke Random, 91
add eax, 10
mov ArraySize, eax
shl eax, 1
invoke VirtualAlloc, NULL, eax, MEM_COMMIT, PAGE_READWRITE
mov Array, eax
invoke printf, addr Message, ArraySize
mov ecx, ArraySize
mov edi, Array
@@:
push ecx
invoke Random, 19999
sub eax, 9999
stosw
invoke printf, addr ArrayItemFormat, eax
pop ecx
loop @B
mov ebx, Array
xor esi, esi
mov edi, -1
mov ecx, ArraySize
FindLoop:
test word ptr [ebx + esi * 2], 1
jnz @F
mov edi, esi
@@:
inc esi
loop FindLoop
test edi, edi
js @F
movsx eax, word ptr [ebx + edi * 2]
inc edi
invoke printf, addr Result, edi, eax
jmp Quit
@@:
invoke printf, addr NoEven
Quit:
invoke printf, addr Prompt
invoke _getch
invoke VirtualFree, Array, NULL, MEM_RELEASE
invoke _exit, NULL
end N168755120
Пример выполнения программы:

Если нужно просматривать все элементы массива (а в вашем случае именно это и требуется) , то используют инструкцию loop.
> Не будет ли инкрементироваться переменная номера элемента массива, после того, как массив закончится
Если вы не вставите команду инкремента после выхода из цикла, то не будет.
> делать цикл с фиксированным количеством выполнений для массива с точным количеством элементов не хочется
Вот пример программы (MASM, Windows x86), в которой кол-во элементов массива не фиксировано, а при каждом запуске программы задаётся случайно. Элементы массива тоже генерируются случайно. Память под массив выделяется автоматически, в соответствии с размером массива.
.586
.model flat, C
option casemap :none
include windows.inc
includelib kernel.lib
includelib msvcrt.lib
VirtualAlloc proto stdcall :dword, :dword, :dword, :dword
VirtualFree proto stdcall :dword, :dword, :dword
printf proto :dword, :vararg
_getch proto
_exit proto :dword
.data
ArrayItemFormat db "%8d", 0
Message db "Дан массив [1 .. %d]:", 13, 10, 0
Result db 13, 10, 10, "Последний чётный элемент массива [%d] = %d", 0
NoEven db 13, 10, 10, "В массиве нет чётных элементов", 0
Prompt db 13, 10, 10, "Для завершения работы нажмите любую клавишу... ", 0
.data?
Seed dd ?
ArraySize dd ?
Array dd ?
.code
Random proc uses edx, Range :dword
mov eax, Seed
mov edx, 08088405h
mul edx
inc eax
mov Seed, eax
mul Range
mov eax, edx
ret
Random endp
N168755120:
rdtsc
mov Seed, eax
invoke Random, 91
add eax, 10
mov ArraySize, eax
shl eax, 1
invoke VirtualAlloc, NULL, eax, MEM_COMMIT, PAGE_READWRITE
mov Array, eax
invoke printf, addr Message, ArraySize
mov ecx, ArraySize
mov edi, Array
@@:
push ecx
invoke Random, 19999
sub eax, 9999
stosw
invoke printf, addr ArrayItemFormat, eax
pop ecx
loop @B
mov ebx, Array
xor esi, esi
mov edi, -1
mov ecx, ArraySize
FindLoop:
test word ptr [ebx + esi * 2], 1
jnz @F
mov edi, esi
@@:
inc esi
loop FindLoop
test edi, edi
js @F
movsx eax, word ptr [ebx + edi * 2]
inc edi
invoke printf, addr Result, edi, eax
jmp Quit
@@:
invoke printf, addr NoEven
Quit:
invoke printf, addr Prompt
invoke _getch
invoke VirtualFree, Array, NULL, MEM_RELEASE
invoke _exit, NULL
end N168755120
Пример выполнения программы:

Выход из цикла, понятное дело, jmp или условный (jne, jle и все такое)
http:// www. cyberforum. ru/assembler/thread444376.html
Самый простой способ поставьте в конце массива какойнибудь спецсимвол и по нему определяйтесь, например символ перевода каретки. Я так воял цикл определения длины строки
Похожие вопросы
- С# , вопрос о выполнении цикла и массивах.
- Ассемблер двумерный массив
- ассемблер .органицация циклов и одномерные массивы.есть несколько вопросов
- Программирование ассемблер. Дан массив из 8 байт. Посчитать количество байт, в которых число нулей и единиц одинаковое
- Здравствуйте помогите в программирование на ассемблере. Нужно зеркально отобразить массив из 256 байт
- Что может ассемблер?
- Почему многие программисты ненавидят ассемблер?Ведь у него куча плюсов!Он позволяет максимально задействовать
- Как а в ассемблере найти минимальный элемент массива?
- Ассемблер. В заданном массиве целых чисел найти самую большую серию подряд стоящих чётных элементов.
- Ассемблер. Дан массив из 6 байт. Посчитать кол-во нулей.