Консультация # 189186: Здравствуйте! У меня возникли сложности с таким вопросом: Дано число в двоичном коде. Разделить его на две составляющие: в первую войдут только четные разряды, во вторую только нечетные разряды. Вычесть из первого числа значение 16, а из второго – 8. ...Консультация # 189187: Уважаемые
эксперты! Пожалуйста, ответьте на вопрос: помогите написать программу для ассемблера ...Консультация # 189189: Здравствуйте! У меня возникли сложности с таким вопросом: Написать программу для нахождения суммы элементов массива...
Здравствуйте! У меня возникли сложности с таким вопросом:
Дано число в двоичном коде. Разделить его на две составляющие: в первую войдут только четные разряды, во вторую только нечетные разряды. Вычесть из первого числа значение 16, а из второго – 8.
mov cx,8
@@01:
shl ax,1
rcl bl,1
shl ax,1
rcl bh,1
loop @@01
sub bh,8
sub bl,16
В АХ загружжается число, в BL - записываются биты с индексами 0,2, ... , а в BH - 1,3, ... ps: Данный вариант был получен совместно с Игорем Витальевичем/ Удачи!
model small
data
dbRes db 10,13,'Result:$'
a dw 14
b dw 48
c dw 26
d dw 3
e dw 44
f dw 6
g dw 37
stack 100h
code
start:
mov ax,@data
mov ds,ax;адресуем сегмент данных
mov ah,9
lea dx,dbRes
int 21h;выводим сообщение
;считаем знаменатель
mov di,b;48
mov ax,a;14
shr ax,1;14/2
sub di,ax;48-14/2
;считаем числитель
mov ax,di
mov si,c;26
sub si,d;3
shl si,1;(26-3)*2
mov ax,e;44
xor dx,dx
mul f;44*6
xchg si,ax
sub ax,si;(26-3)*2-44*6
cwd
;считаем дробь и формулу
idiv di;((26-3)*2-44*6)/(48-14/2)
imul a;14*((26-3)*2-44*6)/(48-14/2)
imul d;3*((26-3)*2-44*6)/(48-14/2)
mov bx,g;37
xchg ax,bx
sub ax,bx;37-14*3*((26-3)*2-44*6)/(48-14/2)
;выводим результат
mov si,10;счисления
xor di,di;флаг минуса
xor cx,cx;счетчик цифр
test ax,8000h;проверяем минус
jz @@01
not ax;меняем знак
inc ax
inc di;взводим флаг
@@01: xor dx,dx
div si;поразядно получаем цифры
push dx;сохраняем их в стеке
inc cx;считаем кол-во
or ax,ax;пока не ноль
jnz @@01
or di,di;проверяем флаг
jz @@02
mov al,'-'
int 29h;выводим минус
@@02: pop ax;извлекаем из стека
add al,'0';преобразовываем в символ
int 29h;выводим
loop @@02
mov ah,4Ch;выход
int 21h
end start
;Нахождение суммы элементов массива
.model small
.code
.startup
call srand ;Инициируем генератор псевдослучайных чисел
call GetNum ;Введем размерность массива
mov N, ax ;сохраним
;выделим место под массив в стеке
shl ax, 1 ;для слов надо в 2 раза больше байт
sub sp, ax ;выделяем место в стеке
mov bp, sp ;адрес начала массива в BP
call SetVector ;заполним массив случайными числами
call PrintVector ;выведем на экран массив
lea dx, sSum
mov ah, 9
int 21h
call CalcSum ;считаем сумму
call PrintNum
mov ah, 0 ;ждем нажатия на клавишу
int 16h
mov ax, N ;подкорректируем стек (для порядка)
mul ax ; вообще говоря, можно не делать...
shl ax, 1
add sp, ax
.exit 0 ;выход в ДОС
stoi proc ;преобразование строки [si] в число AX
xor bx, bx ;здесь будем стоить число
xor cx, cx ;счетчик разрядов
stoi_next:
lodsb ;очередной символ
cmp al, 0dh ;конец стоки?
je stoi_eol
cmp al, '0'
jb stoi_sep ;любая нецифра - разделитель
cmp al, '9'
ja stoi_sep
push ax ;сохраним новый разряд
mov ax, 10
mul bx ;умножим старшие на 10
pop dx ;новый
and dx, 0fh ;'0'-'9' -> 0-9
add ax, dx ;добавляем новый разряд
cmp ax, 255 ;ждем число <=255
ja numError ;больше - ошибка!
mov bx, ax ;сохраняем
inc cx ;считаем
jmp stoi_next ;продолжаем
stoi_sep: ;встретили разделитель
jcxz stoi_next ;были только разделители - на продолжение
; иначе - конец числа и выходим
stoi_eol: ; если числа нет и встретили 0dh - конец строки
mov ax, bx ;число возвращаем в ax
clc ;признак того, что все ок
ret
numError:
stc ;признак ошибки
ret
stoi endp
GetNum proc ;ввод N чисел
lea dx, sEnter
mov ah, 9
int 21h ;приглашение на ввод числа
lea dx, max ;вводим строку с числами
mov ah, 0ah
int 21h
lea si, sBuf ;числовая строка
call stoi ;[si] в число ax
jc GetNum ;C=1 число > 255
test ax, ax
je GetNum
push ax
mov ah, 2
mov dl, 0ah
int 21h
pop ax
ret
GetNum endp
PrintNum proc ;вывод знакового числа в AX на экран
push ax ;сохраним выводимое значение
;выведем знак ' '/'-'
mov dl, ' ' ;считаем пока, что число положительное
test ax, ax ;проверяем число
jge print_sign ;для положительного - на вывод знака
;для отрицательного
pop ax ;уберем из стека число
neg ax ;найдем модуль числа!
push ax ;и сохраним в стеке уже положительное число!
mov dl, '-' ;знак отрицательного числа
print_sign:
mov ah, 2 ;выводим знак
int 21h
pop ax ;AX - модуль числа, т.е. строго положительное
;найдем все разряды числа и сохраним их в стеке в обратном порядке!
xor cx, cx ;счетчик разрядов
mov bx, 10 ;будем делить на 10 (10-ричная с.с.!)
digits_loop: ;цикл нахождения разрядов
xor dx, dx ;готовимся к делению dx:ax/bx
div bx ;dx - остаток от dx:ax/bx, ax - частное
push dx ;остаток - очередной десятичный разряд,
; сохраняем в стеке
inc cx ;считаем
test ax, ax ;проверим число
jne digits_loop ;повторяем, пока есть еще разряды
print_loop: ;выводим разряды в обратном порядке
pop dx ;очередной разряд
or dl, '0' ;число в ASCII-код
mov ah, 2 ;выводим символ
int 21h
loop print_loop ;для всех найденных разрядов, количество в CX
ret
PrintNum endp
PrintVector proc
lea dx, sSourceVector ;строка - заголовок
mov ah, 9
int 21h
xor si, si
mov cx, N
PrintVector_loop:
push cx
mov ax, [bp+si]
call PrintNum
mov dl, ' '
mov ah, 2
int 21h
add si, 2
pop cx
loop PrintVector_loop
mov dl, 0dh
mov ah, 2
int 21h
mov dl, 0ah
mov ah, 2
int 21h
ret
PrintVector endp
CalcSum proc
xor si, si
mov cx, N
xor ax, ax
CalcSum_loop:
add ax, [bp+si]
add si, 2
loop CalcSum_loop
ret
CalcSum endp
;заполнение массива (адрес в BP) случайными знаковыми числами
SetVector proc
mov di, 200 ;будем заполнять числами [-100;99]
mov cx, N ;число элементов вектора
xor si, si ;индекс очередного элемента
SetVector_loop: ;цикл по всем элементам
call rnd ;получаем очередно случайное число
xor dx, dx
div di ;делим на "размах" чисел
sub dx, 100 ;отнимаем от остатка середину, получаем знаковое число!
mov [si+bp], dx ;сохраняем!
add si, 2 ;индексируем следующий элемент
loop SetVector_loop ;циклим
ret
SetVector endp
srand proc ;инициализация генератора псевдослучайных чисел
mov ah, 2ch
int 21h ;возьмем текущее время
mov al, dl ;сотые секунды
mul dh ;умножаем на секунды
mov rand_value, ax ;сохраним, как текущее
ret
srand endp
;простые числа, необходимые для простейшего генератора псевдослучайных чисел
a equ 13013
c equ 16383
;rand = ((a * rand) / 65536) + c
rnd proc
mov ax, a
mul rand_value
add ax, c
mov rand_value, ax
ret
rnd endp
.data
sEnter db "Enter N = $"
sSourceVector db "Source vector = $"
sSum db "Sum = $"
max db 128
cnt db ?
sBuf db 128(?)
N dw ?
rand_value dw ?
end
Консультировал: Лысков Игорь Витальевич (Старший модератор)
Дата отправки: 14.04.2016, 16:20
Команда портала RFPRO.RU благодарит Вас за то, что Вы пользуетесь нашими услугами. Вы только что прочли очередной выпуск рассылки. Мы старались.
Пожалуйста, оцените его. Если совет помог Вам, если Вам понравился ответ, Вы можете поблагодарить автора -
для этого в каждом ответе есть специальные ссылки. Вы можете оставить отзыв о работе портале. Нам очень важно знать Ваше мнение.
Вы можете поближе познакомиться с жизнью портала, посетив наш форум, почитав журнал,
который издают наши эксперты. Если у Вас есть желание помочь людям, поделиться своими знаниями, Вы можете зарегистрироваться экспертом.
Заходите - у нас интересно!