Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 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
15-1181096515
Slider007
2007-06-06 06:21
2007.07.08
С днем рождения ! 6 июня 2007 среда


1-1178721591
TStas
2007-05-09 18:39
2007.07.08
Как программно зазипить папку?


2-1181910702
sergeyst
2007-06-15 16:31
2007.07.08
Где хранить списки?


11-1164864154
Rocket
2006-11-30 08:22
2007.07.08
AnchorRight -Bottom не корректно работают при Parent - GroupBox


15-1181473360
исследователь
2007-06-10 15:02
2007.07.08
Чьи это стихи?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский