Хостинг портала RFpro.ru: Московский хостер Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64 РАССЫЛКИ ПОРТАЛА RFPRO.RU Лучшие эксперты данной рассылки Номер выпуска: | 1407 | Дата выхода: | 26.12.2010, 10:00 | Администратор рассылки: | Лысков Игорь Витальевич (Старший модератор) | Подписчиков / экспертов: | 225 / 68 | Вопросов / ответов: | 4 / 4 | Вопрос № 181471: Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос: Разработать программу которая: Вводит число 567911, затем умножает его на 2. Потом полученное число складывает с 10228. И делит полученную сумму на 10. Выводит рез... Вопрос № 181480: Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос:Помочь с решением задачи на ассемблере ( среда, ассемблер 16 битный под DOS , tasm и tlink , использовать модель памя... Вопрос № 181483: Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос: Осуществить ввод с клавиатуры целых положительных чисел и отсортировать их так, чтобы минимальное число было посередине,а остальные в порядке возрастания разместить справа ... Вопрос № 181487: Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос: Дан массив из целых чисел. Найти в массиве и вывести на экран периоды возрастания, а также найти и вывести максимальный элемент и его номер. Модель Small, ассемблер T... Вопрос № 181471: Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос: Разработать программу которая: Вводит число 567911, затем умножает его на 2. Потом полученное число складывает с 10228. И делит полученную сумму на 10. Выводит результат. Для решения использовать Tasm без использования директивы model, операционная система ДОС, формат ЕХЕ. Приложите к решению пожалуйста блок-схему. И можно комментарии по возможности к каждой строке. Заранее спасибо! Отправлен: 20.12.2010, 09:05 Вопрос задал: Руслан Чернов (Посетитель) Всего ответов: 1 Страница вопроса » Отвечает Лысков Игорь Витальевич (Старший модератор) : Здравствуйте, Руслан Чернов! Задание предусматривает умножение/деление, когда результат не помещается в слово Надо использовать двойные слова. Это раз. Второе: задание так построено, что обычные 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 add ax, 10228 adc dx, 0 ;dx:ax = dx:ax + 10228
push 10 push ax push dx call Div_DW_W ;разделим dx:ax на 10
push ax push dx call PrintNum ;выведем dx:ax
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
end start
181471-block-shema.doc (45.0 кб) ----- Люби своего ближнего, как самого себя Ответ отправил: Лысков Игорь Витальевич (Старший модератор) Ответ отправлен: 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$'
.code start: mov ax, @data mov ds, ax mov es, ax mov ss, ax
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. желательны пояснения. Спасибо за помощь (: Отправлен: 20.12.2010, 20:13 Вопрос задал: Романенко Татьяна Викторовна (Посетитель) Всего ответов: 1 Страница вопроса » Отвечает Лысков Игорь Витальевич (Старший модератор) : Здравствуйте, Романенко Татьяна Викторовна! Обижаете Мы пояснения пишем всегда.  Что непонятно, спрашивайте в мини-форуме. Хочу только остановиться на нескольких моментах: 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. Спасибо за помощь! Отправлен: 20.12.2010, 20:18 Вопрос задал: Романенко Татьяна Викторовна (Посетитель) Всего ответов: 1 Страница вопроса » Отвечает Лысков Игорь Витальевич (Старший модератор) : Здравствуйте, Романенко Татьяна Викторовна! Программа анализирует массив байт, заданный в сегменте данных. Смотрите коментарий в тексте программы. Если что непонятно, мини-форум к Вашим услугам
Код: ;Дан массив из целых чисел. Найти в массиве и вывести на экран периоды возрастания, ;а также найти и вывести максимальный элемент и его номер. .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 (Россия) | Еще номера » | Оценить выпуск » Нам очень важно Ваше мнение об этом выпуске рассылки! Скажите "спасибо" эксперту, который помог Вам! Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА на короткий номер 1151 (Россия) Номер ответа и конкретный текст СМС указан внизу каждого ответа. Полный список номеров » * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов) ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются. *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании. |
Комментариев нет:
Отправить комментарий