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
Assembler
Модераторы: Хыиуду, MOTOCoder, Medved, dr.Jekill
Задача подсчёта количества нулей и единиц в двоичном числе. Может ли кто нибудь закоментить что делает каждая строчка после старта?
Код: Выделить всё
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 ;конец программы

IceFlame, Огромное спасибо))
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
Закоменьте пожалуйста программу в предыдущем посте!!