Форум: "Прочее";
Текущий архив: 2007.07.08;
Скачать: [xml.tar.bz2];
ВнизКак на Assembler подсчитать количество нулевых элементов массива? Найти похожие ветки
← →
SkySpeed (2007-06-04 21:17) [0]К примеру, задан следующий массив c переменной "a":
int a
mas db 4,0,1,0
0,5,0,0
0,0,9,0
1,3,0,8
Как, используя цикл, подсчитать количество нулей в массиве и вывести на экран результат?
Мой вариант:
mov AL,0
mov cl,[SI+DI]
m1: add a,1;увеличиваем переменную "а" на единицу, cl=cl-1
cycl1:
cmp mas[cl],0;сравниваем текущее значение массива с "0"
jz m1;если текущее значение массива = 0, переходим на метку m1
loop cycl1; cl=cl-1
Правильный ли мой вариант? Что и где подправить?
Как вывести на экран результат?
Заранее спасибо!
← →
X9 © (2007-06-04 21:46) [1]Не знаю, что там с остальным кодом, но вот это меня сильно напрягает:
add a,1;увеличиваем переменную "а" на единицу
Есть инструкция inc.
← →
SkySpeed (2007-06-04 21:51) [2]
> X9 © (04.06.07 21:46) [1]
> Не знаю, что там с остальным кодом, но вот это меня сильно
> напрягает:
> add a,1;увеличиваем переменную "а" на единицу
>
> Есть инструкция inc.
Согласен! Для тебя перепишу код:mov AL,0
mov cl,[SI+DI]
m1: inc a;увеличиваем переменную "а" на единицу, cl=cl-1
cycl1:
cmp mas[cl],0;сравниваем текущее значение массива с "0"
jz m1;если текущее значение массива = 0, переходим на метку m1
loop cycl1; cl=cl-1
Но всё же! Что посоветуете?
← →
X9 © (2007-06-04 21:54) [3]> [2] SkySpeed (04.06.07 21:51)
> Согласен! Для тебя перепишу код:
Не стоило утруждаться, это не мне нужно.
← →
default © (2007-06-04 21:55) [4]посоветую читать книгу и экспериментировать
код хрень какая-то
← →
default © (2007-06-04 22:05) [5]вот даже в вопросе уже небрежность к нам
ты спрашиваешь верен-ли код?
то есть ты даже не прошёлся по нему в отладчике!
← →
SkySpeed (2007-06-05 20:34) [6]Вот более правильный код:
Title Second
model small
stack 100h
.data
a db ?
x db 1,0,2,3
db 2,1,0,0
db 0,2,3,0
db 2,5,2,0
.code
start:
mov AX,@data
mov DS,AX
mov si,0
mov di,0
................................
mov AH,04CH
int 21h
end
Вместо ................................ нужно организовать подсчёт нулей - только каким образом?
← →
Rouse_ © (2007-06-05 21:46) [7]
> только каким образом?
Ты спрашиваешь или просишь решить за тебя?
ЗЫ: Сессия ж вроде закончилась...
← →
SkySpeed (2007-06-05 22:06) [8]
> Rouse_ © (05.06.07 21:46) [7]
>
> > только каким образом?
>
> Ты спрашиваешь или просишь решить за тебя?
> ЗЫ: Сессия ж вроде закончилась...
Прошу навести меня на правильный путь
Пробывал так:
XOR SI,SI
mov cx,15
cycl:
cmp x[cx],0
jz m1
LoopNZ cycl
m1: add SI,1
Но в результате ошибка наcmp x[cx],0
- "Illegal memory reference"
Как обратиться правильно к элементу массива, сравнить результат с нулём и если "нуль" - увеличить SI на 1?
ЗЫ: в нашем универе сессия только начинается :-)
← →
Defunct © (2007-06-06 00:06) [9]Если в режиме x86. (16-ти разрадные регистры только) тогда можно так:
mov si, offset <0-й элемент вашего массива>
mov cx, 15
xor bx, bx
__do_count:
lodsb
or al, al
jnz __skip_inc
inc bx
__skip_inc:
dec cx
jnz __do_count
> Но в результате ошибка на cmp x[cx],0 - "Illegal memory reference
Не через все регистры можно адресовать память.
← →
Defunct © (2007-06-06 00:07) [10]забыл отметить - результат будет в bx
если что-то в примере непонятно - спрашивайте
← →
Defunct © (2007-06-06 00:12) [11]> Как обратиться правильно к элементу массива,
> сравнить результат с нулём и если "нуль" - увеличить SI на 1?
mov BX, адрес начала массива
mov SI, номер элемента массива
mov AL, байт с которым будем сравнивать
cmp [BX + SI], AL
Можно также воспользоваться строковой командой LODS (как в примере выше)
строковая команда LODS(B/W/D) считывает данные с адреса DS:[ESI] в регистр AL/AX/EAX, и автоматически увеличивает ESI на 1/2/4.
← →
db2admin © (2007-06-06 10:23) [12]SkySpeed (05.06.07 22:06) [8]
что за универ?
← →
SkySpeed (2007-06-06 13:28) [13]
> Defunct © (06.06.07 00:06) [9]
> Если в режиме x86. (16-ти разрадные регистры только) тогда
> можно так:
>
> mov si, offset <0-й элемент вашего массива>
> mov cx, 15
> xor bx, bx
> __do_count:
> lodsb
> or al, al
> jnz __skip_inc
> inc bx
> __skip_inc:
> dec cx
> jnz __do_count
Спасибо! Работает!
Только в конце пришлось дописатьdec bx
Только не пойму - где идёт обращение к моему массиву "х"?..
Как можно через цикл организовать подсчёт? Думал так, но DX увеличивается на "1" при любых условиях:cycl:
lea bx,x
cmp [BX+SI],0
jz m1
m1: inc dx
Loop cycl
← →
SkySpeed (2007-06-06 13:29) [14]
> db2admin © (06.06.07 10:23) [12]
> SkySpeed (05.06.07 22:06) [8]
> что за универ?
Кременчугский Университет Економики, Информационных Технологий и Управления
Сокращённо КУЕИТУ
← →
oxffff © (2007-06-06 14:24) [15]
> Только не пойму - где идёт обращение к моему массиву "х"?
> ..
LODS/LODSB/LODSW/LODSD—Load String
Loads a byte, word, or doubleword from the source operand into the AL, AX, or EAX register,
respectively. The source operand is a memory location, the address of which is read from the
DS:ESI or the DS:SI registers (depending on the address-size attribute of the instruction, 32 or
16, respectively). The DS segment may be overridden with a segment override prefix.
← →
Bless © (2007-06-06 14:26) [16]
> Только не пойму - где идёт обращение к моему массиву "х"?
> ..
видимо в строчкеmov si, offset <0-й элемент вашего массива>
> Как можно через цикл организовать подсчёт? Думал так, но
> DX увеличивается на "1" при любых условиях:
Как написал, так и увеличивается.
cmp [BX+SI],0
jz m1 ; если 0, то скакнуть на метку m1 (где случится inc). А если
;не 0, то поехали дальше, т.е. опять-таки на ту самую
;cледующую строчку, где произойдет inc
m1: inc dx
Loop cycl
← →
oxffff © (2007-06-06 14:27) [17]P.S. Для lods
After the byte, word, or doubleword is transferred from the memory location into the AL, AX,
or EAX register, the (E)SI register is incremented or decremented automatically according to the
setting of the DF flag in the EFLAGS register. (If the DF flag is 0, the (E)SI register is incremented;
if the DF flag is 1, the ESI register is decremented.) The (E)SI register is incremented
or decremented by 1 for byte operations, by 2 for word operations, or by 4 for doubleword operations.
← →
Defunct © (2007-06-06 14:34) [18]SkySpeed (06.06.07 13:28) [13]
> Только в конце пришлось дописать dec bx
Значит ошибка с размером, лучше правильно задать Cx - (mov cx,14) ;>
> Только не пойму - где идёт обращение к моему массиву "х"?..
Прочитайте комент [11]. Там есть некоторые пояснения.
← →
oxffff © (2007-06-06 15:03) [19]Вот тебе другой вариант
в edi адрес буфера
в ecx кол-во элементов
mov ebx,-1;
xor al,al;
@myLoop:
inc ebx;
repne scasb;
jz @myloop;
на выходе в еbx кол-во элементов
← →
oxffff © (2007-06-06 16:13) [20]Вот пример
procedure TForm1.Button1Click(Sender: TObject);
var a:array[1..200] of byte;
Count:integer;
begin
asm
//подготовка данных
lea edi,a;
mov ecx,200;
xor al,al;
mov ebx,-1;
//поиск
@myLoop:inc ebx;
repne scasb;
jz @myloop;
//результат
mov count,ebx;
end;
showmessage(inttostr(Count));
end;
Страницы: 1 вся ветка
Форум: "Прочее";
Текущий архив: 2007.07.08;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.212 c