Вопрос № 181471: Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос: Разработать программу которая: Вводит число 567911, затем умножает его на 2. Потом полученное число складывает с 10228. И делит полученную сумму на 10. Выводит рез...
Вопрос № 181480: Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос:Помочь с решением задачи на ассемблере ( среда, ассемблер 16 битный под DOS , tasm и tlink , использовать модель памя...
Вопрос № 181483: Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос: Осуществить ввод с клавиатуры целых положительных чисел и отсортировать их так, чтобы минимальное число было посередине,а остальные в порядке возрастания разместить справа ...
Вопрос № 181487: Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос: Дан массив из целых чисел. Найти в массиве и вывести на экран периоды возрастания, а также найти и вывести максимальный элемент и его номер. Модель Small, ассемблер T...
Вопрос № 181471:
Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос: Разработать программу которая: Вводит число 567911, затем умножает его на 2. Потом полученное число складывает с 10228. И делит полученную сумму на 10. Выводит результат. Для решения использовать Tasm без использования директивы model, операционная система ДОС, формат ЕХЕ. Приложите к решению пожалуйста блок-схему. И можно комментарии по возможности к каждой строке. Заранее спасибо!
Отвечает Лысков Игорь Витальевич (Старший модератор) :
Здравствуйте, Руслан Чернов! Задание предусматривает умножение/деление, когда результат не помещается в слово Надо использовать двойные слова. Это раз. Второе: задание так построено, что обычные mul/div не работают! Будет переполнение! Т.о. возникла необходимость в написании собственных подпрограмм умножения/деления двойного слова на слово. При этом предполагаем, что результат умножения/сложения не выходит за пределы двойного слова. PS
Число 567911 вводим с клавиатуры...
Код:
;Вводит число 567911, затем умножает его на 2. ;Потом получен
ное число складывает с 10228. ;И делит полученную сумму на 10. ;Выводит результат.
.186 ;чтобы можно было использовать push <число> assume cs:code, ds:data, es:data code segment para public 'code' start: mov ax, data mov ds, ax mov es, ax ;пусть es=ds=data
lea dx, sNum mov ah, 9 int 21h ;ждем число N
mov bNum, 80 ;задаем максимальное значение строки lea dx, bNum mov ah, 0ah int 21h ;вводим числовую строку
lea dx,
sResult mov ah, 9 int 21h ;выведем сообщение о результате
lea si, bBuf ;строка call stol ;преобразовываем в число dx:ax
push 2 push ax push dx call Mul_DW_W ;умножим на dx:ax на 2
Exit: lea dx, sPress ;выведем приглаш
ение нажать на любую клавишу mov ah, 9 int 21h
mov ah, 0 ;ждем int 16h
mov ax, 4c00h int 21h ;выход в ДОС
;умножаем столбиком двойное слово на слово ;параметры: ;1 - старшее слово множимого mul_dw_hi equ word ptr [bp+4] ;2 - младшее слово множимого mul_dw_lo equ word ptr [bp+6] ;3 - множитель mul_w equ word ptr [bp+8] ;результат в dx:ax Mul_DW_W proc push bp mov bp, sp ;параметры будем адресовать через стек mov ax, mul_w ;ax =
множитель mul mul_dw_lo ;умножаем на младшее слово множителя push ax ;сохраняем младшее слово результата xchg dx, mul_dw_hi ;dx = ст слово множителя, mul_dw_hi = ст слово предыд умножения mov ax, mul_w ;ax = множитель mul dx ;умножаем на старшее слово множителя add ax, mul_dw_hi ;добавим ст слово предыд умножения mov dx, ax ;ст слово произведения pop ax ;мл слово произведения pop bp ret 6 ;уберем из стека 3 параметра Mul_DW_
W endp
;делим двойное слово на слово ;параметры: ;1 - ст слово делимого div_dw_hi equ word ptr [bp+4] ;2 - мл слово делимого div_dw_lo equ word ptr [bp+6] ;3 - делитель div_w equ word ptr [bp+8] ;результат: dx:ax - частное, bx - остаток Div_DW_W proc push bp mov bp, sp ;параметры будем адресовать через стек ;разделим старшее слово на делитель mov ax, div_dw_hi ;ax = ст слово делимого xor dx, dx ;dx = 0 div div_w ; push ax ;сохраним ст разряд
(ст слово) результата ;разделим мл слово на делитель ;при этом учитываем, что остаток от предыдущего деления есть ст слово для этого mov ax, div_dw_lo ;мл слово делимого div div_w ;ax = мл слово частного mov bx, dx ;bx = остаток pop dx ;dx = ст слово частного pop bp ret 6 ;уберем из стека 3 параметра Div_DW_W endp
;выводим двойное слово ;сначала сохраняем в стеке разряды (делением на 10), затем выводим в обратном порядке ;д
ля деления используем Div_DW_W ;параметры: ;1 - ст слово num_hi equ [bp+4] ;1 - мл слово num_lo equ [bp+6] PrintNum pr
oc push bp mov bp, sp ;параметры будем адресовать через стек mov ax, num_lo mov dx, num_hi ;число dx:ax xor cx, cx ;счетчик разрядов DivLoop: ;цикл преобразования в разряды push 10 push ax push dx call Div_DW_W ;dx:ax = dx:ax / 10 push bx ;сохраним в стеке остаток inc cx ;считаем test dx, dx ;проверим оба слова на 0 jnz DivLoop test ax, ax ;продолжаем, пока не дойдем до 0 jnz DivLoop PrLoop: ;цикл вывода в обратном порядке pop ax ;берем
число 0-9 из стека or al, '0' ;преобразовываем в символ '0'-'9' int 29h ;выводим loop PrLoop
pop bp ret 4 ;уберем из стека 2 параметра PrintNum endp
stol proc ;преобразование строки [si] в число DX:AX xor ax, ax ;будем стоить 32-битное число в dx:ax xor dx, dx xor cx, cx ;счетчик разрядов stol_next: mov bl, [si] ;очередной символ inc si cmp bl, 0dh ;конец стоки? je st
ol_eol cmp bl, '0' jb stol_sep ;любая нецифра - разделитель cmp bl, '9' ja stol_sep
push 10 push ax push dx call Mul_DW_W ;dx:ax = dx:ax * 10 and bx, 0fh ;'0'-'9' -> 0-9 add ax, bx ;добавляем новый разряд adc dx, 0 ;учитываем перенос inc cx ;считаем jmp stol_next ;продолжаем stol_sep: ;встретили разделитель jcxz stol_next ;были только разделители - на продолжение ; иначе - конец числа и выходим stol_eol: ;
если числа нет и встретили 0dh - конец строки ret ;число возвращаем в dx:ax stol endp code ends
data segment para public 'data' sNum db 'Enter N: $' sResult db 0ah,'Result: $' sPress db 0dh,0ah,'Press any key$' ;буфер для ввода числовой строки (для функции 0ah) bNum db ? ;максимальный размер буфера bCount db ? ;реальный размер строки bBuf db 80 dup (?) ;сама строка data ends
Ответ отправил: Лысков Игорь Витальевич (Старший модератор)
Ответ отправлен: 20.12.2010, 12:12
Номер ответа: 264926 Украина, Кировоград Тел.: +380957525051 ICQ # 234137952 Mail.ru-агент: igorlyskov@mail.ru
Оценка ответа: 5
Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"?
Отправить SMS#thank 264926
на номер 1151 (Россия) |
Еще номера »
Вопрос № 181480:
Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос:Помочь с решением задачи на ассемблере ( среда, ассемблер 16 битный под DOS , tasm и tlink , использовать модель памяти small) : Найти 7 наименьших элементов массива А(15).Записать их в массив В. Просьба написать пояснение к операторам в программе . Вот пример одной из програмы в данной среде.
Код:
.model small .stack 48 .data string db 10 dup (?),'$' chet db 5 dup (?) nech db 5 dup (?) ic db 0 it db 0 .code mov ax,@data<
br> mov ds,dx mov es,ax mov ss,ax lea di,string mov cl,10 mov ah,1 c1: int 21h and al,ofh sosb loop c1 mov bl,2 mov bh,3 lea si,string lea di,chet lea bp,nech mov cl,10 mov dh,0 c2: xor ax,ax lodsb mov dl,al div bl cmp ah,0 je cd xor ax,ax mov al,dl div bh cmp ah,0 je nd jmp cc cd: xor ax,ax mov al,dh
div bl cmp ah,0 jne c06 mov al,dl or al,30h stosb inc ic jmp cc c06: cmp dl,0 je n06 cmp dl,6 je n06 cmp cc nd: xor ax,ax mov al,dh div bl cmp ah,0 je cc n06: or dl,30h mov [bp],dl inc bp inc it cc: inc dh loop c2 mov cl,ic lea si,chet lea di,string rep movsb mov cl,it
lea si,nech rep movsb mov al,'$' mov ah,'^' sc: scasb jz vyvod dec di mov [di],ah inc di jmp sc vyvod: mov dl,10 mov ah,2 int 21h lea dx,string mov ah,9 int 21h mov ah,4ch int 21h end
Отправлен: 20.12.2010, 16:45
Вопрос задал: кирюша (Посетитель)
Всего ответов: 1 Страница вопроса »
Отвечает Лысков Игорь Витальевич (Старший модератор) :
Здравствуйте, кирюша! Вот Вам программа. Если что неясно - милости просим в мини-форум
Код:
;Найти 7 наименьших элементов массива А(15).Записать их в массив В .model small .data A db 15 dup
(?) ;массив из 15 байт-символов lenA equ $-A ;длина его (=15) B db 7 dup (?) ;массив для первых 7 минимальных lenB equ $-B ;длина (=7) db '$' ;для вывода с помощью 9 функции sEnter db 'Enter 15 symbols: $' sFirst db 0dh,0ah,'First 7 min: $' sAny db 0dh,0ah,'Press any key$'
lea dx, sEnter ;приглашение на ввод 15 символ
ов mov ah, 9 int 21h
lea di, A ;адрес массива mov cx, lenA ;число элементов mov ah, 1 c1: int 21h ;ждем символ stosb ;сохраняем loop c1 ;ровно 15 штук
;сортируем методом пузырька lea si, A ;адрес начала массива mov cx, lenA ;cx - число сортируемых элементов dec cx ;число сравнений SortLoop: ;цикл по поиску очередного минимального lea di, [si+1] ;начинаем со следующего push cx ;сохраним счетчик mov al, [si] ;текущий минимальный
по адресу [si] SearchMinLoop: ;цикл по всем последующим ;сравниваем текущий со всеми последующими cmp al, [di] ;если текущий минимальный <= последующего, jbe SortNext ; то обходим обмен ;меняем местами элементы xchg al, [di] mov [si], al ;по адресу [si] и в al новый минимальный SortNext: inc di ;на следующий последующий loop SearchMinLoop inc si ;на следующий текущий pop cx ;восстановим счетчик сравнений loop SortL
oop
;копируем 7 первых в массив В lea si, A ;откуда lea di, B ;куда mov cx, lenB ;7 штук rep movsb
lea dx, sFirst mov ah, 9 int 21h ;Сообщение о 7 миним
lea dx, B mov ah, 9 int 21h ;сами 7 минимальные
lea dx, sAny mov ah, 9 int 21h ;any key
mov ah, 8 int 21h ;ждем any key
mov ah, 4ch int 21h
end start
----- Люби своего ближнего, как самого себя
Ответ отправил: Лысков Игорь Витальевич (Старший модератор)
Ответ отправлен: 21.12.2010, 12:19
Номер ответа: 264966 Украина, Кировоград Тел.: +380957525051 ICQ # 234137952 Mail.ru-агент: igorlyskov@mail.ru
Оценка ответа: 5
Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"?
Отправить SMS#thank 264966
на номер 1151 (Россия) |
Еще номера »
Вопрос № 181483:
Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос: Осуществить ввод с клавиатуры целых положительных чисел и отсортировать их так, чтобы минимальное число было посередине,а остальные в порядке возрастания разместить справа и слева (поочереди) от минимального и вывести на экран. например, введены числа: 153789; получить: 851379 модель памяти SMALL, ассемблер TASM. желательны пояснения. Спасибо за помощь (:
Отвечает Лысков Игорь Витальевич (Старший модератор) :
Здравствуйте, Романенко Татьяна Викторовна! Обижаете Мы пояснения пишем всегда. Что непонятно, спрашивайте в мини-форуме. Хочу только остановиться на нескольких моментах: 1) считаем, что числовая строка не превышает 64 байта (проверка не производится) 2) для сортировки применен метод пузырька (надеюсь, знаком ). 3)
чтобы обеспечить попеременного размещения справа/слева, использован вызов подпрограммы, адрес которой лежит в регистре 4) для смены адреса подпрограммы использован прием двоекратного применения операции xor. Сначала со смещением одной подпрограммы, затем другой. Этим достигается смена одного адреса на другой.
Код:
.model small .code .startup
lea dx, sEnter mov ah, 9 int 21h ;приглашаем ввести число
lea bx, sNum ;адрес числовой строки EnterLoop: mov ah, 1 int 21h ;ждем код cmp al, 0dh je Sort ;по Enter-у идкм дальше cmp al, '0' jb EnterLoop ;нецифры игнорируем cmp al, '9' ja EnterLoop mov [bx]
,al ;сохраняем inc bx ;на следующую позицию jmp EnterLoop
Sort: ;сортируем методом пузырька lea si, sNum ;адрес начала массива mov cx, bx ;адрес конца sub cx, si ;cx - число сортируемых элементов cmp cx, 2 ;0 и 1 нет смысла сортировать jb Exit dec cx ;число сравнений SortLoop: ;цикл по поиску очередного минимального lea di, [si+1] ;начинаем со следующего push cx ;сохраним счетчик mov al
, [si] ;текущий минимальный по адресу [si] SearchMinLoop: ;цикл по всем последующим ;сравниваем текущий со всеми последующими cmp al, [di] ;если текущий минимальный <= последующего, jbe SortNext ; то обходим обмен ;меняем местами элементы xchg al, [di] mov [si], al ;по адресу [si] и в al новый минимальный SortNext: inc di ;на следующий последующий loop SearchMinLoop inc si ;на следующий текущий pop cx ;восстановим счетчик сравнений loop SortLoop
;строим
новое число lea si, sNum ;адрес начала массива mov cx, bx ;адрес конца sub cx, si ;cx - число элементов
lea di, sSort ;адрес начала сортированного массива mov ax, cx ;длина shr ax, 1 ;половина adc di, ax ;начало записи в сортированном массиве ;причем для нечетного необходимо добавить 1 ;мы этого добиваемся сложив с битом переноса mov bx, di ;bx - адрес слева, di - справа lea bp, rout_2 ;подпрограмма отраб
отки записи push cx ;сохраним длину массива FormLoop: lodsb ;читаем очередной call bp ;вызов или rout_1, или rout_2 xor bp, offset rout_1 ;смена адреса rout_1 на rout_2, и наоборот! xor bp, offset rout_2 ;интересный "финт" :) loop FormLoop ;по всем pop bx ;длина массива mov byte ptr sSort[bx], '$' ;вставим в конце '$' для 9 функции
lea dx, sResult mov ah, 9 int 21h ;выведем результат
lea dx, sSort mov ah, 9 int 21h ;отсортированную
строку
Exit: lea dx, sAny mov ah, 9 int 21h ;any key
mov ah, 1 int 21h ;ждем any key
mov ax, 4c00h int 21h ;выход в ДОС
rout_1 proc ;подпрограмма записи справа mov [di], al inc di ret rout_1 endp
rout_2 proc ;подпрограмма записи слева dec bx mov [bx], al ret rout_2 endp
.data sEnter db 'Enter number: $' sResult db 0dh,0ah,'Result n
umber: $' sAny db 0dh,0ah,'Press any key$' sNum db 64 dup (?) sSort db 64 dup (?)
end
----- Люби своего ближнего, как самого себя
Ответ отправил: Лысков Игорь Витальевич (Старший модератор)
Ответ отправлен: 21.12.2010, 02:29
Номер ответа: 264957 Украина, Кировоград Тел.: +380957525051 ICQ # 234137952 Mail.ru-агент: igorlyskov@mail.ru
Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"?
Отправить SMS#thank 264957
на номер 1151 (Россия) |
Еще номера »
Вопрос № 181487:
Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос: Дан массив из целых чисел. Найти в массиве и вывести на экран периоды возрастания, а также найти и вывести максимальный элемент и его номер. Модель Small, ассемблер Tasm. Спасибо за помощь!
Отвечает Лысков Игорь Витальевич (Старший модератор) :
Здравствуйте, Романенко Татьяна Викторовна! Программа анализирует массив байт, заданный в сегменте данных. Смотрите коментарий в тексте программы. Если что непонятно, мини-форум к Вашим услугам
Код:
;Дан массив из целых чисел. Найти в массиве и вывести на экран периоды возрастания, ;а также найти и вывести максимальный элемент и его номер. .model small .code .startup
lea dx, sIncrease ;выведем сообщение о выводе периодов возрастания mov ah, 9 int 21h
xor si, si ;индекс в массиве чисел mov cx, len_num ;количество чисел mov dx, 8000h ;dh - максимальный элемен
т, 80h = -128 (самое маленькое число) ;dl - индекс макс элемента mov bx, 0080h ;bh - текущее число возрастания ;bl - предыдущий элемент, 80h = -128 (самое маленькое число) mov ah, 0 ;ah - число периодов возрастания MainLoop: ;цикл по всем элементам mov al, num[si] ;очередной ;сравниваем с максимальным cmp al, dh jle Increase mov dx, si ;запомним индекс (в dl) mov dh, al ;и новое максимальное значение
Increase: ;проверим на периоды возрастания cmp al,
bl ;сравниваем с предыдущим jle endInc ;<= - возраст последовательность закончилась либо ее не было ;идет возраст последовательность cmp bl, 80h ;для первого элемента je SetStart ;просто сохраняем начало последовательности и новый предыдущий элемент inc bh ;для всех последующих - считаем jmp new_code ;на сохранение нового предыдущего элемента endInc: ;возраст последовательность закончилась либо ее не было cmp bh, 0 ;есл
и последовательности не было je SetStart ;сохраняем начало последовательности и новый предыдущий элемент inc ah ;была - считаем call PrInc ;выводим текущую последовательность, начиная с [di] и длиной bh SetStart: mov di, si ;адрес начала последовательности new_code: mov bl, al ;сохраним новый предыдущий элемент inc si ;на следующий элемент loop MainLoop ;по всем элементам массива
;проверим последнюю последовательность cmp bh, 0 ;было ли что-то возрастающее? je cmpInc ;не
было, на проверку, было ли вообще inc ah ;считаем call PrInc ;и выводим jmp PrMax ;на вывод максимального элемента cmpInc: cmp ah, 0 ;проверим, а были ли вообще возраст последовательности jne PrMax ;были - на вывод макс lea dx, sNotFound ;сообщение, что не были mov ah, 9 int 21h PrMax: ;вывод на экран push dx ;сохраним lea dx, sMax mov ah, 9 int 21h pop dx push dx mov al, d
l ;индекс с 0 call PrByte lea dx, sEqual mov ah, 9 int 21h pop dx mov al, dh ;максимальный элемент call PrByte ;выход lea dx, sAny mov ah, 9 int 21h ;any key
mov ah, 8 int 21h ;ждем any key
mov ax, 4c00h int 21h ;выход в ДОС
PrInc proc ;вывод последовательности, начиная с [di] и длиной bh push ax dx inc bh ;добавим самый первый, который не считался IncreasePrint: mov al, num[di] ;элемент inc di ;на след call PrByte ;выводим,
в конце пробел dec bh ;счетчик - 1 jnz IncreasePrint mov dl, 0dh ;перевод строки int 21h mov dl, 0ah int 21h pop dx ax ret PrInc endp
PrByte proc ;вывод байта, как числовой строки (со знаком) push bx cx mov bl, 10 ;будем делить на 10 xor cx, cx ;счетчик цифр test al, al ;проверим на минус jns divLoop ;положительное push ax mov dl, '-' mov ah, 2 int 21h
;выведем минус pop ax neg al ;модуль divLoop: mov ah, 0 ;подготавливаемся к делению div bl ;ax / 10 push ax ;с
охраним ah - остаток - очередную цмладшую цифру inc cx ;ситаем cmp al, 0 ;еще есть десятичные разряды? jne divLoop prLoop: ;выведем в обратном порядке pop ax ;извлечем цифру в ah mov dl, ah ;для функции 2 or dl, '0' ;0-9 -> '0'-'9' mov ah, 2 int 21h ;выведем loop prLoop ;по всем цифрам mov dl, ' ' int 21h pop cx bx ret PrByte endp
.data sIncrease db 'Increase periods:',0dh,0ah,'$' sNotFound db 'Not
found',0dh,0ah,'$' sMax db 'Max = num[ $' sEqual db '] = $' sAny db 0dh,0ah,'Press any key$' ;примерный массив num db -3,-4,-5,-5,3,0,1,2,1,-1,3,5,7,6,5,6,7,8,4,-3 ;его длина len_num equ $-num
end
----- Люби своего ближнего, как самого себя
Ответ отправил: Лысков Игорь Витальевич (Старший модератор)
Ответ отправлен: 21.12.2010, 10:59
Номер ответа: 264961 Украина, Кировоград Тел.: +380957525051 ICQ # 234137952 Mail.ru-агент: igorlyskov@mail.ru
Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"?
Отправить SMS#thank 264961
на номер 1151 (Россия) |
Еще номера »
Оценить выпуск »
Нам очень важно Ваше мнение об этом выпуске рассылки!
* Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи.
(полный список тарифов)
** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
*** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.