Другие языки программирования и технологии

Цикл обхода массива в ассемблере

Нужно, пока что, найти последний четный элемент в массиве. Учу ассемблер недавно, поэтому не знаю как организовать выход из цикла. Не будет ли инкрементироваться переменная номера элемента массива, после того, как массив закончится? Не находил функцию по нахождению длины массива в ассемблере, а делать цикл с фиксированным количеством выполнений для массива с точным количеством элементов не хочется. Надеюсь, что смог объяснить внятно. Пишу под 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

Пример выполнения программы:
Сергей Феденев
Сергей Феденев
51 590
Лучший ответ
Выход из цикла, понятное дело, jmp или условный (jne, jle и все такое)
http:// www. cyberforum. ru/assembler/thread444376.html
Самый простой способ поставьте в конце массива какойнибудь спецсимвол и по нему определяйтесь, например символ перевода каретки. Я так воял цикл определения длины строки
Шамиль Хамзин
Шамиль Хамзин
35 594