Хостинг портала RFpro.ru: Московский хостер Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64 РАССЫЛКИ ПОРТАЛА RFPRO.RU Лучшие эксперты данной рассылки Номер выпуска: | 1398 | Дата выхода: | 13.12.2010, 18:30 | Администратор рассылки: | Лысков Игорь Витальевич (Старший модератор) | Подписчиков / экспертов: | 224 / 66 | Вопросов / ответов: | 3 / 3 | Вопрос № 181166: Здравствуйте, уважаемые эксперты! Прошу Вас помочь с решением следующей задачи: Разработать две подпрограммы, одна из которых сравнивает две строки по лексикографическому порядку, а другая обменивает значения двух строк. Разработать программу,... Вопрос № 181161: Здравствуйте, уважаемые эксперты! Прошу Вас помочь с решением следующей задачи: Разработать две подпрограммы, одна из которых соединяет две строки в одну, а другая обрезает строки до заданной длины (или дополняет пробелами, если длина строки... Вопрос № 181162: Здравствуйте, уважаемые эксперты! Прошу Вас помочь с решением следующей задачи: Посчитать за какое время процессор выполнит 1 000 000 команд mov DI, SI; add DI, SI; mul SI. Для подсчёта времени использовать вектор 1Ch. Выводить на экран прео... Вопрос № 181166: Здравствуйте, уважаемые эксперты! Прошу Вас помочь с решением следующей задачи:
Разработать две подпрограммы, одна из которых сравнивает две строки по лексикографическому порядку, а другая обменивает значения двух строк. Разработать программу, которая вводит с клавиатуры несколько строк (конец ввода пустая строка) и сортирует их в лексикографическом порядке.
Для решения использовать Tasm без использования директивы model, операционная система ДОС, формат ЕХЕ. Приложите к решению пожалуйста блок-схему. Отправлен: 08.12.2010, 16:04 Вопрос задал: Ivan Afonin (Посетитель) Всего ответов: 1 Страница вопроса » Отвечает Лысков Игорь Витальевич (Старший модератор) : Здравствуйте, Ivan Afonin! Вот и программа Место под строки выделяем в конце, за кодовым сегментом и данными Ограничиваемся 80 байтами на строку. Сначала "накидываем" строки, потом сортируем методом пузырька Обмен решил сделать очень просто: меняем все 80 байт... Ну и выводим отсортированные строки.
Код: ;Разработать две подпрограммы, одна из которых сравнивает две строки ;по лексикографическому порядку, а другая обменивает значения двух строк. ;Разработать программу, которая вводит с клавиатуры несколько строк ;(конец ввода пустая строка) и сортирует их в лексикографическом порядке
.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
mov N, 0 ;число строк GetStrLoop: ;цикл ввода строк lea dx, sString mov ah, 9 int 21h ;ждем строку
lea dx, bNum mov ah, 0ah int 21h ;вводим строку
xor bx, bx mov bl, bCount ;длина введенной строки, одновременно, смещение конца строки
test bx, bx ;= 0 -> пустая строка jz Sort ;на сортировку
mov bBuf[bx], 0 ;вставим в конце строки код 0
;скопируем в массив строк mov ax, 80 ;длина одного элемента массива mul N ;индекс элемента массива mov di, ax ;смещение в массиве lea si, bBuf ;введенная строка CopyLoop: lodsb mov bStr[di], al inc di cmp al, 0 jne CopyLoop ;копируем с завершующим нулем inc N ;считаем строки - элементы массива mov al, 0ah ;переход на следующую строку int 29h jmp GetStrLoop ;и на ввод слежующей строки
Sort: ;сортировка mov cx, N ;число сортируемых строк dec cx ;число сравнений xor si, si ;индекс строки в массиве SortLoop: ;цикл по поиску очередного минимального lea di, [si+1] ;начинаем со следующей push cx ;сохраним счетчик SearchMinLoop: ;цикл по всем последующим ;сравниваем текущий со всеми последующими push di ;индекс последующей push si ;индекс текущей call StrCompare ;сравниваем jbe SortNext ;если меньше или равно, то обходим обмен ;меняем местами строки push di ;индекс последующей push si ;индекс текущей call StrChange ;по адресу [si] новая минимальная SortNext: inc di ;на следующую последующую loop SearchMinLoop inc si ;на следующую текущую pop cx ;восстановим счетчик сравнений loop SortLoop
;выводим lea dx, sResult mov ah, 9 int 21h
mov cx, N ;число строк lea bx, bStr ;начало строк StrLoop: mov si, bx ;начало текущей строки add bx, 80 ;для следующей строки PrintLoop: lodsb ;очередной символ cmp al, 0 ;признак конца je Next int 29h ;выводим jmp PrintLoop Next: mov al, 0dh ;перевод строки int 29h mov al, 0ah int 29h loop StrLoop ;по всем
lea dx, sPress ;выведем приглашение нажать на любую клавишу mov ah, 9 int 21h
mov ah, 0 ;ждем int 16h
mov ax, 4c00h int 21h ;выход в ДОС
;сравнение строк ;параметры подпрограммы num1 equ word ptr [bp+4] ;индекс первой строки num2 equ word ptr [bp+6] ;индекс второй строки StrCompare proc push bp ;сохраним старый bp mov bp, sp ;будем адресовать параметры в стеке push si di ;сохраним используемые регистры mov ax, 80 ;преобразуем индекс строки в смещение в массиве строк mul num1 mov si, ax ;смещение первой mov ax , 80 mul num2 mov di, ax ;смещение второй CmpLoop: mov al, bStr[si] ;очередной символ из первой строки cmp al, bStr[di ] ;сравниваем с символом второй строки jne StrCmpRet ;не равно - на выход inc di inc si ;инкремент смещений cmp al, 0 ;сравниваем на конец строки jne CmpLoop ;если не 0, то продолжаем сравнивать StrCmpRet: ;результат во флагах pop di si ;восстанавливаем регистры pop bp ret 4 ;убираем параметры StrCompare endp
;обмен строк, меняем, не мудствуя лукаво, все 80 байт :) ;параметры подпрограммы num1 equ word ptr [bp+4] ;индекс первой строки num2 equ word ptr [bp+6] ;индекс второй строки StrChange proc push bp ;сохраним старый bp mov bp, sp ;будем адресовать параметры в стеке push cx si di ;сохраним используемые регистры mov ax, 80 ;преобразуем индекс строки в смещение в массиве строк mul num1 mov si, ax ;смещение первой mov ax, 80 mul num2 mov di, ax ;смещение второй mov cx, 40 ;число слов (80/2) ChgLoop: mov ax, word ptr bStr[si] ;обмениваем по словам xchg ax, word ptr bStr[di] mov word ptr bStr[si], ax inc si ;смещение на следующие слова inc si inc di inc di loop ChgLoop ;по всем 40 словам pop di si cx pop bp ret 4 StrChange endp
code ends
data segment para public 'data' N dw 0 ;число строк sString db 'Enter string: $' sResult db 0ah,0ah,'Sorted strings: ',0dh,0ah,'$' sPress db 0dh,0ah,'Press any key$' ;буфер для ввода строки (для функции 0ah) bNum db 80 ;максимальный размер буфера bCount db ? ;реальный размер строки bBuf db 80 dup (?) ;сама строка bStr label byte ;адрес в конце программы для хранения строк data ends
end start
181166-block-sch.doc (55.0 кб) ----- Люби своего ближнего, как самого себя Ответ отправил: Лысков Игорь Витальевич (Старший модератор) Ответ отправлен: 08.12.2010, 17:50 Номер ответа: 264594 Украина, Кировоград Тел.: +380957525051 ICQ # 234137952 Mail.ru-агент: igorlyskov@mail.ru
Оценка ответа: 5 Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"? | Отправить SMS #thank 264594 на номер 1151 (Россия) | Еще номера » | Вопрос № 181161: Здравствуйте, уважаемые эксперты! Прошу Вас помочь с решением следующей задачи:
Разработать две подпрограммы, одна из которых соединяет две строки в одну, а другая обрезает строки до заданной длины (или дополняет пробелами, если длина строки меньше заданной). Разработать программу, которая вводит с клавиатуры число N, затем вводит несколько строк (конец ввода пустая строка) и формирует новую строку, состоящую из первых N символов каждой введённой строки.
Для решения использовать Tasm без использования директивы model, операционная система ДОС, формат ЕХЕ. Приложите к решению пожалуйста блок-схему. Отправлен: 08.12.2010, 10:09 Вопрос задал: Ivan Afonin (Посетитель) Всего ответов: 1 Страница вопроса » Отвечает Лысков Игорь Витальевич (Старший модератор) : Здравствуйте, Ivan Afonin! Программа приведена ниже. Единственное замечание, которое хочу сделать: Результирующую строку, куда мы пишем результат работы программы (склеянные усеченные подстроки) я задаю после программы и данных. Т.о. длина может быть практически любой.
Код: ;Разработать две подпрограммы, одна из которых соединяет две строки в одну, ;а другая обрезает строки до заданной длины (или дополняет пробелами, ;если длина строки меньше заданной). Разработать программу, которая ;вводит с клавиатуры число N, затем вводит несколько строк ;(конец ввода пустая строка) и формирует новую строку, ;состоящую из первых N символов каждой введённ ой строки.
.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 si, bBuf ;строка call stoi ;преобразовываем в число mov N, ax ;сохраним
mov bResult, 0 ;пустая строка
MainLoop: ;цикл ввода строк lea dx, sString mov ah, 9 int 21h ;ждем строку
lea dx, bNum mov ah, 0ah int 21h ;вводим строку
xor bx, bx mov bl, bCount ;длина введенной строки, одновременно, смещение конца строки
test bx, bx ;= 0 -> пустая строка jz PrintResult ;на вывод результирующей строки
mov bBuf[bx], 0 ;вставим в конце строки код 0
push N ;заданна я длина push offset bBuf ;адрес введенной строки call Trunc ;обрежем до заданной длины
push offset bBuf ;адрес введенной строки push offset bResult ;адрес результирующей строки call StrCat ;склеим jmp MainLoop ;на повтор
PrintResult: lea dx, sResult mov ah, 9 int 21h ;выведем сообщение о результате
lea si, bResult ;результирующая строка PrintLoop: lodsb ;очередной символ cmp al, 0 ;признак конца je Exit int 29h ;выводим jmp PrintLoop
Exit: lea dx, sPress ;выведем приглашение нажать на любую клавишу mov ah, 9 int 21h
mov ah, 0 ;ждем int 16h
mov ax, 4c00h int 21h ;выход в ДОС
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 ;добавляем новый разряд mov bx, ax ;сохраняем inc cx ;считаем jmp stoi_next ;продолжаем stoi_sep: ;встретили разделитель jcxz stoi_next ;были только разделители - на продолжение ; иначе - конец числа и выходим stoi_eol: ; если числа нет и встретили 0dh - конец строки mov ax, bx ;число возвращаем в ax ret stoi endp
;обрезка строки ;параметры подпрограммы pStr equ [bp+4] ;адрес строки num equ [bp+6] ;число оставляемых символов Trunc proc push bp ;сохраним старый bp mov bp, sp ;будем адресовать параметры в стеке mov di, pStr ;адрес строки mov cx, num ;число оставляемых символов TruncLoop: mov al, [di] inc di cmp al, 0 ;проверим на конец строки l oopnz TruncLoop ;выходим из цикла, когда cx==0 или FZ==1 jnz TruncZero ;если FZ==0, то введенная строка больше числа num - усекаем TruncSpace: ;если FZ==1, то встретили раньше времени 0 - дополним пробелами inc cx ;подправим cx, уменьшенное лишний раз командой loopnz dec di ;и di, увеличенное inc-ом mov al, ' ' ;дополним пробелами rep stosb ;cx раз TruncZero: mov byte ptr [di],0 ;закроем строку 0 pop bp ;восстановим bp ret 4 ;уберем из стека параметры Trunc endp
;склеивание двух строк ;параметры подпрограммы pStrOut equ [bp+4] ;адрес, куда доклеиваем pStrIn equ [bp+6] ;адрес, что доклеиваем StrCat proc push bp ;сохраним старый bp mov bp, sp ;будем адресовать параметры в стеке mov di, pStrOut ;адрес выходной строки mov al, 0 ;найдем символ - конец строки mov cx, 0ffffh ;заведомо большое число repne scasb ;ищем конец строки dec di ;вернем di на позицию нуля mov si, pStrIn ;адрес исходной строки CatLoop: lodsb ;читаем символ исходной строки stosb ;копируем cmp al, 0 ;дошли до конца ? jne CatLoop pop bp ;восстановим bp ret 4 ;уберем из стека параметры StrCat endp
code ends
data segment para public 'data' sNum db 'Enter N: $' sString db 0ah,'Enter string: $' sResult db 0ah,'Result string: $' sPress db 0dh,0ah,'Press any key$' ;буфер для ввода числовой строки (для функции 0ah) bNum db ? ;максимальный размер буфера bCount db ? ;реальный размер строки bBuf db 80 dup (?) ;сама строка N dw ? ;"водораздел" количества символов bResult label byte ;адрес в конце программы для формирования ; результирующей строки data ends
end start
181161-block-sch.doc (50.0 кб) ----- Люби своего ближнего, как самого себя Ответ отправил: Лысков Игорь Витальевич (Старший модератор) Ответ отправлен: 08.12.2010, 12:05 Номер ответа: 264588 Украина, Кировоград Тел.: +380957525051 ICQ # 234137952 Mail.ru-агент: igorlyskov@mail.ru
Оценка ответа: 5 Комментарий к оценке: Отлично! :) Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"? | Отправить SMS #thank 264588 на номер 1151 (Россия) | Еще номера » | Вопрос № 181162: Здравствуйте, уважаемые эксперты! Прошу Вас помочь с решением следующей задачи:
Посчитать за какое время процессор выполнит 1 000 000 команд mov DI, SI; add DI, SI; mul SI. Для подсчёта времени использовать вектор 1Ch. Выводить на экран преобразованное в ASCII коды число тиков таймера, затраченное на операцию.
Для решения использовать Tasm без использования директивы model, операционная система ДОС, формат ЕХЕ. Приложите к решению пожалуйста блок-схему. Отправлен: 08.12.2010, 10:28 Вопрос задал: Ivan Afonin (Посетитель) Всего ответов: 1 Страница вопроса » Отвечает Лысков Игорь Витальевич (Старший модератор) : Здравствуйте, Ivan Afonin! Программа готова. Увеличил число выполнения цикла до 100 000 000. Иначе, выходит слишком быстро. А так - порядка секунды...
181162-block-sch.doc (42.0 кб) В блок-схеме счетчик отработки фрагмента для наглядности я сделал, как одну переменную "Счетчик" Хотя там, на самом деле, два вложенных цикла
Код: ;Посчитать за какое время процессор выполнит 1 000 000 команд ;mov DI, SI ;add DI, SI ;mul SI ;Для подсчёта времени использовать вектор 1Ch. ;Выводить на экран преобразованное в ASCII коды число тико в таймера, ;затраченное на операцию.
.186 ;чтобы можно было использовать push <число> assume cs:code, ds:data code segment para public 'code' start: mov ax, 351ch int 21h ;узнаем вектор 1ch в es:bx
mov ax, data mov ds, ax ;ds = data
mov Off_1c, bx ;сохраним старый адрес в сегменте данных mov Seg_1c, es
lea dx, new_1c ;установим новый адрес push cs ;обработчика прерывания 1ch pop ds ;ds:dx mov ax, 251ch int 21h
mov ax, data mov ds, ax ;ds = data
mov si, 123 ;что-нибудь, чтобы что-то там считало :) mov bx, Ticks ;сохраним значение счетчика тиков в bx mov cx, 10000 ;будем считать 10000 * 10000 = 100 000 000 циклов Loop_1: push cx mov cx, 10000 Loop_2: mov di, si ;тестовые команды add di, si mul si
loop Loop_2 pop cx loop Loop_1
mov ax, Ticks ;новое число тиков sub ax, bx ;число затраченных тиков
push ax ds ;сохраним ax и ds lds dx, dword ptr Off_1c ;ds:dx - адрес старого вектора mov ax, 251ch int 21h ;восстановим! pop ds ;ds = data
lea dx, sTicks ;выведем пояснение mov ah, 9 int 21h
pop ax ;число тиков call PutNumber ;выведем Exit: lea dx, sPress ;выведем приглашение нажать на любую клавишу mov ah, 9 int 21h
mov ah, 0 ;ждем int 16h
mov ax, 4c00h int 21h ;выход в ДОС
PutNumber proc ;преобразование числа из ax в строку и вывод на экран xor cx, cx ;счетчик разрядов mov bx, 10 ;делим на 10 DivLoop: ;цикл преобразования в разряды cwd ;подготавливаем dx:ax к делению idiv bx ;dx = очередному младшему разряду push dx ;сохраним в стеке inc cx ;считаем test ax, ax ;продолжаем, пока не дойдем до 0 jnz DivLoop PrLoop: ;цикл вывода в обратном порядке pop ax ;берем число 0-9 из стека or al, '0' ;преобразовывае м в символ '0'-'9' int 29h ;выводим loop PrLoop ret PutNumber endp
new_1c: ;подпрограмма отработки 1ch push ds ;сохраним ds push data pop ds ;ds = data inc Ticks ;инкремент Ticks в сегменте данных! pushf ;вызовем старый обработчик, сначала надо pushf, т.к. выход по iret! call dword ptr Off_1c;адрес в переменной в сегменте данных pop ds ;восстановим ds iret ;возврат из прерывания code ends
data segment para public 'data' Off_1c dw 0 ;смещение старого вектора 1c Seg_1c dw 0 ;сегмент старого вектора 1c Ticks dw 0 ;счетчик имков таймера sTicks db 'Ticks count = $' sPress db 0dh,0ah,'Press any key$' bStr db 16 dup (?) ;строка для формирования числовой строки data ends
end start
----- Люби своего ближнего, как самого себя Ответ отправил: Лысков Игорь Витальевич (Старший модератор) Ответ отправлен: 08.12.2010, 14:30 Номер ответа: 264591 Украина, Кировоград Тел.: +380957525051 ICQ # 234137952 Mail.ru-агент: igorlyskov@mail.ru Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"? | Отправить SMS #thank 264591 на номер 1151 (Россия) | Еще номера » | Оценить выпуск » Нам очень важно Ваше мнение об этом выпуске рассылки! Скажите "спасибо" эксперту, который помог Вам! Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА на короткий номер 1151 (Россия) Номер ответа и конкретный текст СМС указан внизу каждого ответа. Полный список номеров » * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов) ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются. *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании. |
Комментариев нет:
Отправить комментарий