Консультация № 188099
13.10.2015, 10:33
0.00 руб.
13.10.2015, 10:45
0 3 1
Здравствуйте! Прошу помощи в следующем вопросе:
Помогите,пожалуйста решить задачи в Ассемблере. Я в нем полный ноль.Завтра сдать надо,а я представления не имею как...((


1. Найти максимальный элемент, делящийся на 3.
2.Дано целое число N (> 1). Если оно является недостаточным, то есть сумма положительных
делителей, кроме самого себя, меньше N, то вывести True, иначе вывести False.
3.Дана строка и число n. Верно ли, что в ней есть по крайней мере n подряд идущих букв a?

Обсуждение

давно
Посетитель
7438
7205
13.10.2015, 10:54
общий
13.10.2015, 10:57
Адресаты:
Здравствуйте, Екатерина!
Несколько вопросов.
1) Во всех заданиях числа и строку вводим или задаем в тексте программы?
2) Какой компилятор (ассемблер) используем (TASM, MASM, FASM,...)?
3) Модель памяти? TINY, SMALL, ...
4) Формируем COM или EXE ?
4) Сегменты задаем явно или используем, например, .model tiny ?

PS Что ж Вы так-то дотянули?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
13.10.2015, 11:01
общий
Если есть желающие написать одну из трех программок, отпишитесь здесь... Жду до 15:00
Нет - сам сделаю
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
13.10.2015, 18:51
общий
это ответ
Здравствуйте, Попушой Екатерина Витальевна!
Программы под компилятор FASM, формируют COM-файл
1) Программа читает из определенной в тексте все числа, проверяет их на делимость на 3 и ищет среди них максимальный
Затем выводится найденное число, десятичные разряды которого находятся делением на 10 и сохранением в стеке.
[code h=200]
;Найти максимальный элемент, делящийся на 3
use16
org 100h
lea bx, [numbers] ;строка чисел
mov cx, 5 ;их количество
call FindMaxDiv3 ;ищем требуемое число в последовательности чисел, результат в регистре AX
;AX = 0, если таких чисел нет
lea dx, [sNum] ;заголовок сообщения
call PrintNum ;выводим число

lea dx, [sPress] ;сообщение нажать любую клавишу
mov ah, 9 ;функция вывода строки
int 21h

mov ah, 0 ;ждем нажатие на клавишу
int 16h

mov ax, 4c00h
int 21h ;выход из программы

;разбор строки и поиск максимального числа, делящегося на 3,
;адрес массива чисел в регистре BX, количество в CX
;вернет в регистре AX (= 0, если таких чисел нет)
FindMaxDiv3:
xor si, si ;здесь будет искомое число
FindMaxDiv3_loop:
mov ax, [bx] ;берем очередное число
inc bx ;смещаем адрес для следующего
inc bx

call CmpMaxDiv3 ;проверяем

loop FindMaxDiv3_loop ;и по всем
mov ax, si ;найденное число возвращаем в AX
ret

CmpMaxDiv3: ;поиск максимального из делещихся на 3
mov bp, 3 ;будем делить на 3
xor dx, dx ;подготавливаем делимое, т.к. будем делить DX:AX / BP
push ax ;сохраним само число
div bp ;делим, DX - остаток, AX - частное
pop ax ;восстановим число
test dx, dx ;проверим остаток, =0 - делится нацело
jnz CmpMaxDiv3_ret ;нет, это число нам неинтересно
cmp ax, si ;делится - ищем максимальное
jb CmpMaxDiv3_ret ;у нас уже есть большее
mov si, ax ;сохраним, как новое максимальное
CmpMaxDiv3_ret:
ret

PrintNum: ;вывод числа из AX в виде последовательности цифр
push ax ;сохраним число, чтобы вывести заголовок
mov ah, 9 ;выведем строку-заголовок, адрес в dx
int 21h
pop ax

test ax, ax ;проверим, "а был ли мальчик"
jne PrintNum_continue ;был! на вывод числа!

lea dx, [sNotFound] ;таких чисел нет!
mov ah, 9 ;выводим сообщение
int 21h
ret ; и выходим

PrintNum_continue: ;продолжаем вывод
mov bp, 10 ;будем делить на 10
xor cx, cx ;счетчик цифр
div_loop: ;цикл получения десятичных разрядов
xor dx, dx ;подготовимся для очередного деления
div bp ;в dx остаток - очередной десятичный разряд
push dx ;сохраним в стеке (от младшего к старшему)
inc cx ;посчитаем
test ax, ax ;есть еще десятичные разряды?
jnz div_loop ;продолжим

pr_loop: ;цикл вывода десятичных цифр-символов
pop dx ;востановим очередной разряд (от старшего к младшему)
add dl, '0' ;символ цифры
mov ah, 2 ;выведем
int 21h ;
loop pr_loop ;по всем цифрам
ret

;
sNumbers db 0dh,0ah,"Enter numbers: $"
sNum db 0dh,0ah,"Maximum number, divided by 3: $"
sPress db 0dh,0ah,"Press any key$"
sNotFound db "not found$"
numbers dw 123, 432, 32111, 11136, 57345
[/code]
2) Должно быть все понятно из комментариев
[code h=200]
;Дано целое число N (> 1). Если оно является недостаточным, то есть сумма положительных
;делителей, кроме самого себя, меньше N, то вывести True, иначе вывести False.
use16
org 100h
mov AX, N ;исходное число

call CalcNum ;считаем суму делителей, число и результат в AX

lea dx, [sTrue] ;сначала считаем, что True
cmp ax, N ;проверяем условие
jb print_str ;если меньше, то остается True
lea dx, [sFalse] ;иначе False

print_str: ;выводим
mov ah, 9 ;функция вывода строки
int 21h

mov ah, 0 ;ждем нажатие на клавишу
int 16h

mov ax, 4c00h
int 21h ;выход из программы

CalcNum: ;считаем суму делителей, число и результат в AX
;искать будем, проверяя, делится ли число на все числа
;большие 2 и меньшие половины исходного
mov bx, 1 ;сумма делителей, 1 будет всегда
mov cx, 1 ;начальный делитель
mov di, ax
shr di, 1 ;максимальный делитель (N/2)
CalcNum_loop: ;цикл поиска
inc cx ;увеличиваем делитель
cmp cx, di ;дошли до края?
jae CalcNum_ret
xor dx, dx ;готовимся к делению
push ax ;сохраним исходное число
div cx ;делим DX:AX/CX
pop ax ;восстановим исходное число
test dx, dx ;проверяем остаток
jnz CalcNum_loop ;не делится нацело - обходим
add bx, cx ;складываем делители
CalcNum_ret:
mov ax, bx ;результат в AX
ret

N dw 2364
sTrue db 0dh,0ah,"True$"
sFalse db 0dh,0ah,"False$"
sPress db 0dh,0ah,"Press any key$"
[/code]
3) Ну и третья...
[code h=200]
;Дана строка и число n. Верно ли, что aв ней есть по крайней мере n подряд идущих букв a

use16
org 100h
lea si, [string] ;исходное строка
mov dx, [n] ;число n
mov bl, 'a' ;искомый символ

call CalcStr ;проверяем строку, результат в AX=1(верно) или =0(неверно)

lea dx, [sYes] ;сначала считаем, что верно
cmp ax, 1 ;проверяем условие
je print_str ;если меньше, то остается Yes
lea dx, [sNo] ;иначе No

print_str: ;выводим
mov ah, 9 ;функция вывода строки
int 21h

mov ah, 0 ;ждем нажатие на клавишу
int 16h

mov ax, 4c00h
int 21h ;выход из программы

;проверяем строку, результат в AX=1(верно) или =0(неверно)
;параметры: si - адрес строки, dx - число n, bl - символ
CalcStr:
xor cx, cx ;обнулим счетчик подряд идущих символов bl
CalcStr_loop: ;цикл по символам строки
lodsb ;читаем очередной в al=ds:[si] с автоинкрементом si
cmp al, 0 ;строка заканчивается нулем
je ret_no ;дошли до конца, значит n подряд идущих символов не нашли
cmp al, bl ;сравниваем текущий символ с искомым
jne CalcStr ;не равен - продолжаем поиск, обнуляя счетчик
inc cx ;равен - считаем
cmp cx, dx ;и сравниваем с числом n
jb CalcStr_loop ;меньше - смотрим дальше
mov ax, 1 ;больше или равно - нашли n подряд идущих символа bl
ret
ret_no: ;не нашли - возвращаем 0
xor ax, ax
ret

n dw 3
string db 'asdfgaakkkkaaallll',0
sYes db 0dh,0ah,"Yes$"
sNo db 0dh,0ah,"No$"
sPress db 0dh,0ah,"Press any key$"
[/code]
5
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Форма ответа