Страница 1 из 1

Assembler

Добавлено: 05 дек 2009, 15:02
assis2007
Задача подсчёта количества нулей и единиц в двоичном числе. Может ли кто нибудь закоментить что делает каждая строчка после старта?
stseg segment stack
dw 256 dup(?)
stseg ends

dseg segment
a db 11100011b
ed db 0
nol db 0
dseg ends

cseg segment
assume cs:cseg, ds:dseg, ss:stseg

start:
mov ax,dseg
mov ds,ax
mov bl,a
mov cx,8
begin:
mov dx,bx
and dx,1
cmp dx,1
je label1
inc nol
jmp label2
label1: inc ed
mov dl,ed
label2:
shr bx,1
dec cx
cmp cx,0
jne begin

mov al,nol
mov bl,ed

cmp al,bl
jg labelnol
je labelravno

mov cx,1
jmp labelkonec

labelnol:
mov cx, 0
jmp labelkonec

labelravno:
mov cx,2

labelkonec:
mov ax,4C00h
int 21h
cseg ends
end start

Re: Assembler

Добавлено: 05 дек 2009, 23:50
IceFlame

Код: Выделить всё

stseg segment stack   ;объявление сегмента стека размером в 256 слов=512 байт
dw 256 dup(?)
stseg ends ;конец сегмента стека

dseg segment ;объявление сегмента данных
a db 11100011b ;наше искомое число
ed db 0  ;счетчик единиц
nol db 0	;счетчик нулей
dseg ends	;конец сегмента кода

cseg segment	;начало сегмента кода
assume cs:cseg, ds:dseg, ss:stseg	;принимаем, что cs указывает на сегмент кода,
;ds - сегмент данных (но все равно надо инициализировать), ss - на сегмент стека
start:	;начало программы
mov ax,dseg	;инициализция регистра ds значений смещения сегмента данных
mov ds,ax
mov bl,a	;в bl искомое число
mov cx,8	;число битов в числе
begin:		;начало цикла подсчета бит
mov dx,bx	;записываем в dx текущее число
and dx,1	;и выделяем нулевой бит
cmp dx,1	;и проверяем, не равен ли он 1
je label1	;если равен 1, то переходим на метку label1
inc nol		;иначе увеличиваем счетчик нулей
jmp label2	;и перескакиваем на метку label2
label1: inc ed	;увеличиваем счетчик единиц
mov dl,ed	;копируем кол-во единиц в dl (Зачем? - История умалчивает)
label2:
shr bx,1	;сдвигаем регистр bx на один бит вправо для проверки следующего бита
dec cx		;уменьшаем счетчик цикла
cmp cx,0	;и сравниваем его с нулем
jne begin	;если еще не равен нулю, переходим к началу цикла
			;впрочем три последние строчки можно было заменить одной командой loop begin
mov al,nol	;в al - кол-во нулей
mov bl,ed	;в bl - кол-во единиц

cmp al,bl	;сравниваем кол-во нулей и единиц
jg labelnol	;если нулей больше
je labelravno	;если одинаково

mov cx,1	;если единиц больше, то в cx - 1
jmp labelkonec	;конец программы

labelnol:
mov cx, 0	;если нулей больше, то в cx - 0
jmp labelkonec

labelravno:
mov cx,2	;если единиц и нулей одинаково, то в cx - 2

labelkonec:
mov ax,4C00h	;стандартный выход из DOS-программы
int 21h		;вызов системного прерывания DOS
cseg ends	;конец сегмента кода
end start	;конец программы 
Писалось после пары банок джин-тоника. если что - не обессудьте :)

Re: Assembler

Добавлено: 06 дек 2009, 14:13
assis2007
IceFlame, Огромное спасибо))

Re: Assembler

Добавлено: 10 дек 2009, 21:20
assis2007
IceFlame, А можете ещё одну программу закоментить
datseg segment
family db 'Ivanov'
i dw 9
x dw 35
y dw 0
regim db 00001001b
datseg ends
stseg segment stack
dw 255 dup(?)
stseg ends
codseg segment
assume cs:codseg, ds:datseg, ss:stseg
clear proc; очистка экрана
mov AH,0
mov AL,3
int 10h
ret
clear endp
cursor proc; установка курсора
mov AH,02h
int 10h
ret
cursor endp
vivod proc; вывод символа
mov AH,09h
int 10h
ret
vivod endp
start:
mov ax,datseg
mov ds,ax
xor ax,ax
call clear; очистка экрана
mov cx,i; цикл 28 этераций
mov dh,byte ptr y;
mov dl,byte ptr x
mov BP,y
;
Sikl:
call cursor
mov al,family[BP]
mov bl,regim
push cx
mov cx,1
call vivod
pop cx
inc dh
inc BP
loop Sikl
;
mov ah,10h
int 16h
call clear
mov ah,10h
int 16h
mov ah,4ch
int 21h
codseg ends
end start

Re: Assembler

Добавлено: 19 дек 2009, 15:46
assis2007
Закоменьте пожалуйста программу в предыдущем посте!!