Рассылка закрыта
При закрытии подписчики были переданы в рассылку "RFpro.ru: Ассемблер? Это просто! Учимся программировать" на которую и рекомендуем вам подписаться.
Вы можете найти рассылки сходной тематики в Каталоге рассылок.
RusFAQ.ru: программирование на языке Assembler
Информационный Канал Subscribe.Ru |
/ КОМПЬЮТЕРЫ И ПО / Языки программирования / Assembler
Выпуск № 176
от 04.07.2005, 00:50
Администратор: | Калашников О.А. |
В номере: | Вопросов: 15, Ответов: 35 |
Вопрос № 22722: Евгений Иванов мне сказал, что 6 и 7 функции - очистить участки экрана. Каким образом их вызвать?...
Вопрос № 22724: Еще один вопрос: bh=номер видеостраницы Что такое номер видеостраницы ? Объясните пожалуйста. ;-)...
Вопрос № 22726: Здравствуйте, скажите пожалуйста, какие программы могут запретить перехват прерываний и есть ли какие-нибудь возможности эти запреты обходить? ...
Вопрос № 22727: Спасибо Евгений Иванов и все, все, все !!! С вашей помощью я написал можно сказать первую свою программу на ассемблере. Еще один вопрос у меня есть файл моего BIOS - а AV8X4M13 с расширением AWD (AV8X4M13.AWD) можно ли его &qu...
Вопрос № 22761: Скажите пожалуйста как обратится к первому сектору жесткого диска и записать его в файл. Ведь там хранится загрузчик операционной системы. Ну а потом восстановить таким же образом....
Вопрос № 22767: Объясните пожалуйста что такое PSP Что делает команда LEA и чем она оличается от MOV...
Вопрос № 22769: регистры процессора SI (Source Index) - индекс источника. DI (Destination Index) - индекс назначения. Кто-нибудь может обьяснить их назначение и на очень простом примере продеманстрировать их применение. ..
Вопрос № 22770: Как правильно скомпилировать COM - файл в MASM 6.14 и TASM 4.1, что бы получить *.lst, *.obj, *.com Какие нужны параметры командной строки...
Вопрос № 22774: У меня возник вопрос про сегмент стека. stack segment stack db 100 dup (?) stack ends assume ss:stack, cs:code, ds:data, es:data1 Почему для сегмента стека не нужно следующее: mov ax, stack mov ss, ax...
Вопрос № 22782: Вопрос такой: Какие сегменты можно определить в программе, которая будет преобразована в COM файл ?...
Вопрос № 22783: Определение стека в COM-файле отсутствует. Как ведет себя COM-файл с учетом этого обстоятельства?...
Вопрос № 22787: Я чего - то понять не могу, если CS=DS=SS sp=0fffe, то есть все в одной куче что ли ? допустим MOV AX, ffff MOV DS, AX то в стеке места не останится, ведь он растет в сторону уменьшения адресов. Выходит заполняя стек умень...
Вопрос № 22796: Передо мной задача такая: Нужно написать программу для вычисления 12 чисел Фибоначчи: 1,1,2,3,5,13,... Я чего - то вопроса непойму Фибоначчи - это число ряда чисел, т.е. массива или последовательности, представляющее собой сумму двух ...
Вопрос № 22801: Уважаемые программисты дайте ссылку если есть на какую - нибудь статью или литературу, где встречается Фибоначчи. Я считаю мне нужно ее прочесть....
Вопрос № 22805: Уважаемый "Ayl" и все остальные Я совсем ничего незнаю о фибоначчи но по вашему алгоритму у меня почемуто получается. 1 1 3 5 7 9 11 13 Я что-то опять непонял. Должно же быть так: 1 1 2 3 5 8 и т.д....
Вопрос № 22.722 |
Евгений Иванов мне сказал, что 6 и 7 функции - очистить участки экрана. Каким образом их вызвать? |
Отправлен: 27.06.2005, 16:40 Вопрос задал: Терсков Алексей Николаевич (статус: Посетитель) Всего ответов отправлено: 2 |
Отвечает: Евгений Иванов Здравствуйте, Терсков Алексей Николаевич! я же тебе посылал файл! там список всех функций. Int 10h, 06h Scroll Window Up Scrolls a specified window upward a specified number of lines. Entry AH = 06h AL = Number of lines to scroll (if 0, clear entire window) BH = Display attribute for blank lines CH = Row number of upper left corner CL = Column number of upper left corner DH = Row number of lower right corner DL = Column number of lower right corner заноси в регистры вот то, что сказано. и вызывай. удачи! --------- Что имеем - не храним, потерявши - плачем |
Ответ отправил: Евгений Иванов (статус: Профессор) Отправлен: 27.06.2005, 17:08 |
Отвечает: ASMодей Здравствуйте, Терсков Алексей Николаевич! На самом деле - это функции сдвига экрана вверх (функция 6) и вниз (функция 7) на несколько строк. Но с их помощью действительно можно очистить часть экрана. Например если сдвинуть экран на 3 строки вверх, а потом - на 3 строки вниз, то три верхних строки очистятся. Вызываются они также как и остальные функции. AH = 06 или 07 AL = число строк для сдвига BH = цветовой атрибут для новых строк CH = номер строки верхнего левого угла экрана CL = номер колонки верхнего левого угла экрана DH = номер строки нижнего правого угла экрана DL = номер колонки нижнего правого угла экрана |
Ответ отправил: ASMодей (статус: Профессионал) Отправлен: 27.06.2005, 20:57 |
Вопрос № 22.724 |
Еще один вопрос: bh=номер видеостраницы Что такое номер видеостраницы ? Объясните пожалуйста. ;-) |
Отправлен: 27.06.2005, 17:33 Вопрос задал: Терсков Алексей Николаевич (статус: Посетитель) Всего ответов отправлено: 2 |
Отвечает: Ayl Здравствуйте, Терсков Алексей Николаевич! В текстовых режимах объем видеопамяти, требуемый для работы, составляет от 2 до 4 Кб. Реальный объем видеопамяти значительно больше (даже на старых картах он был как минимум 16Кб). Соответственно, появляется "лишняя" память, достаточная для хранения информации о еще как минимум 3-х экранных страницах. Это и сделано аппаратным образом. Т.е. ты можешь изменить начальное смещение отображаемой на экран страницы и мгновенно получить новое изображение. По умолчанию используется страница 0. Но можно использовать и другие. С помощью BIOS номер страницы задается в регистре BH. При программировании адаптера напрямую нужно самому учитывать нужное смещение. --------- Трудное - то, что можно сделать немедленно. Невозможное - то, для выполнения чего требуется немного больше времени |
Ответ отправил: Ayl (статус: Профессор) Отправлен: 27.06.2005, 18:29 |
Отвечает: Евгений Иванов Здравствуйте, Терсков Алексей Николаевич! в текстовом режиме есть страницы (в графическом тоже они есть, но не во всех). на экран может быть выведено только X на Y элементов. Допустим 80*25. это 2000 символов - 4000 байт. всё это дело округляется до 4096 и разделяется на страницы. то есть, видеопамять (видеобуфер) разделяется на области. активная может быть одна. в это время можно работать с другими! при этом быстрее идёт доступ. это удобно для рисовки сложных объектов. менять смещение показа - для включения страницы можно с помощью функций bios. или с помощью портов. например, графический режим 640*480 следующий алгоритм создавал самостоятельно по описанию регистров VGA: proc get_port_data mov dx,3D4h mov al,0Ch call port_read_w mov bh,ah mov al,0Dh call port_read_w mov bl,ah mov ax,bx mov cx,wptr [cs:sch2] ;#E ret endp proc set_port_data mov dx,3D4h mov bl,al mov al,0Ch out dx,ax inc ax mov ah,bl out dx,ax ret endp proc port_read_w out dx,al jcxz $+2 jcxz $+2 inc dx mov ah,al in al,dx xchg al,ah dec dx ret endp Чтобы сместить экран вверх, вот подпрограмма: up_up: ;=4d pusha call get_port_data mov bx,80*12 cmp ch,13 jnc m84d mov bx,80 m84d: cmp ch,159 jnz m94d mov bx,200 m94d: sub ax,bx jc top_up ret_all_move: mov wptr [cs:data_scroll-2],ax call set_port_data ret_up_up: popa test bptr [cs:sch2],4 jnz m90i92 ret m90i92: pop ax jmp m90i9 top_up: sub ax,ax jmp ret_all_move тут применяется различные вспомогательные счётчики и т.п. но суть, думаю, ясна ;) всё это применяется в драйвере для телевизора: http://superforest.narod.ru/research_computer2tv.htm Всё это было 7 лет назад ;) Хорошие были времена! На твоём мониторе чёрно/белом обычном телевизионного стандарта! я получал картинку 800 на 350 точек!!! всё было чётко и не мелькало! 800 точек держит отлично по горизонтали, а вот по вертикали только 350..при увеличении до 600 мелькает озверенно! поэтому включал 350 точек, но использовал смещение экрана по нажатию средней кнопки мыши - жмёшь её и двигаешь мышь вверх/вниз - и экран смещался ;))) потом это работало в win3.11 (порты работали) и также это РАБОТАЛО в win95! тоже доступ к портам был!!!! я помню, обалдел! а вот в win98 уже порты не работали...но потом у меня монитор появился цветной хороший;) Удачи! Прикреплённый файл: Загрузить >> |
Ответ отправил: Евгений Иванов (статус: Профессор) Отправлен: 27.06.2005, 18:47 |
Вопрос № 22.726 |
Здравствуйте, скажите пожалуйста, какие программы могут запретить перехват прерываний и есть ли какие-нибудь возможности эти запреты обходить? |
Отправлен: 27.06.2005, 17:45 Вопрос задал: Unticipated (статус: Посетитель) Всего ответов отправлено: 2 |
Отвечает: Евгений Иванов Здравствуйте, Unticipated! для этого нужен защищённый режим. уровень ядра. нулевой. в реальном режиме можно полностью запретить прерывания и не давать управление другим программам. тогда никто ничего вообще сделать не сможет. помню, как использовал NMI-прерывание, чтобы всплывать. ЛЮБАЯ программа прерывалась. у меня была кнопка к процессору подпаяна - к его контакту, где вход NMI (386-процессор). я на неё нажимал - и всплывала моя резидентная программа. ;) это было круто;) Удачи! --------- Что имеем - не храним, потерявши - плачем |
Ответ отправил: Евгений Иванов (статус: Профессор) Отправлен: 27.06.2005, 20:29 |
Отвечает: ASMодей Здравствуйте, Unticipated! В реальном режиме вообще ничего запретить нельзя. Любая программа может подменить вектор прерывания и встать по иерархии над всякой запрещающей программой. |
Ответ отправил: ASMодей (статус: Профессионал) Отправлен: 27.06.2005, 21:02 |
Вопрос № 22.727 |
Спасибо Евгений Иванов и все, все, все !!! С вашей помощью я написал можно сказать первую свою программу на ассемблере. Еще один вопрос у меня есть файл моего BIOS - а AV8X4M13 с расширением AWD (AV8X4M13.AWD) можно ли его "Дизассемблировать" и какой нужен Дизассемблер ? и вообще где взять хороший Дизассемблер. Под Дизассемблером я понимаю такую программу, которая переводит двоичный файл в коды ассемблера. Приложение: |
Отправлен: 27.06.2005, 17:57 Вопрос задал: Терсков Алексей Николаевич (статус: Посетитель) Всего ответов отправлено: 1 |
Отвечает: Евгений Иванов Здравствуйте, Терсков Алексей Николаевич! файл сжат архиватором LHA. при этом он состоит из разных областей. используй программы с www.rom.by/ --------- Что имеем - не храним, потерявши - плачем |
Ответ отправил: Евгений Иванов (статус: Профессор) Отправлен: 27.06.2005, 19:24 |
Вопрос № 22.761 |
Скажите пожалуйста как обратится к первому сектору жесткого диска и записать его в файл. Ведь там хранится загрузчик операционной системы. Ну а потом восстановить таким же образом. |
Отправлен: 28.06.2005, 09:49 Вопрос задал: Терсков Алексей Николаевич (статус: Посетитель) Всего ответов отправлено: 3 |
Отвечает: DSota Здравствуйте, Терсков Алексей Николаевич! Чтение загрузчика с диска: mov al,Disk;(disk: 0-A,1-b,2-c,...) mov cx,1 mov dx,0 lea bx,readbuf;Адрес буфера для чтения int 25h Запись загрузчика с диска: mov al,Disk;(disk: 0-A,1-b,2-c,...) mov cx,1 mov dx,0 lea bx,readbuf;Адрес буфера для записи int 26h --------- Открыть глаза навстречу солнцу. |
Ответ отправил: DSota (статус: Практикант) Отправлен: 28.06.2005, 10:14 |
Отвечает: Ayl Здравствуйте, Терсков Алексей Николаевич! Тебе первый сектор раздела или MBR нужен? Если первый сектор раздела, то см. ответ DSota, только учти, что прерывания 25h и 26h оставляют на вершине стека 1 слово (значение регистра флагов перед вызовом прерывания), которое нужно оттуда убрать: ... int 25h / int 26h pop ax ... Если же тебе нужен MBR, то к нему ты не достучишься через эти прерывания. Для него нужно использовать прерывание 13h, функции 2 (чтение) и 3 (запись). Набор параметров для них идентичен, т.ч. опишу только чтение: MBR находится в секторе с физическим номером (0, 0, 1) - головка 0, дорожка (цилиндр) 0, сектор 1. Тогда параметры для вызова будут такими: AH = 02h AL = 1 (количество считываемых секторов) CH = 0 (младшие 8 бит номера дорожки/цилиндра) CL = 1 (формат CC ssssss, где CC - старшие 2 бита номера дорожки, ssssss - 6-тибитный номер сектора) DL = 80h (идентификатор диска: 0-3 - дискеты, 80h - 81h - HDD0 - HDD1) DH = 0 (номер головки) ES:BX = адрес буфера для чтения (512 байт или больше). --------- Трудное - то, что можно сделать немедленно. Невозможное - то, для выполнения чего требуется немного больше времени |
Ответ отправил: Ayl (статус: Профессор) Отправлен: 28.06.2005, 13:58 |
Отвечает: Mad_C Здравствуйте, Терсков Алексей Николаевич! В дополнение к ответу Ayl, в приложении процедуры для записи и чтения MBR Приложение: |
Ответ отправил: Mad_C (статус: 1-ый класс) Отправлен: 28.06.2005, 16:27 |
Вопрос № 22.767 |
Объясните пожалуйста что такое PSP Что делает команда LEA и чем она оличается от MOV |
Отправлен: 28.06.2005, 12:38 Вопрос задал: Терсков Алексей Николаевич (статус: Посетитель) Всего ответов отправлено: 3 |
Отвечает: Ayl Здравствуйте, Терсков Алексей Николаевич! PSP - Program Segment Prefix - префикс программного сегмента. Это 256-байтная область, выделяемая ОС перед запуском программы, в которой содержится важная информация о выполняемой программе. В частности, там сохранябтся вектора прерываний 22h, 23h и 24h, информация об открытых файлах, 2 блока FCB и область обмена DTA, PSP родительской программы, сегментный адрес окружения программы, командная строка без имени вызванной программы, а также инструкция int 20h в 0-м и первом байтах PSP. Именно поэтому COM-программу можно завершать с помощью команды retn, т.к. CS в COM-программе указывает на PSP, а в стек ОС помещает 0 перед передачей управления вызванной программе. retn выбирает из стека этот 0 и управление передается на команду по адресу CS:0, т.е. на команду int 20h - завершение программы. LEA - загрузить эффективные адрес (EA) в указанный регистр. MOV - скопировать второй операнд в первый. Это абсолютно 2 разные команды, хотя в одном случае их действие идентично, а именно для команд: lea reg, label mov reg, OFFSET label В этом случае в reg будет помещено смещение метки label. Но с помощью команды lea можно выполнять арифметические действия, например: lea ax, [bx+si+5] в регистр ax будет помещено значение выражения bx + si + 5. В 386+ процессорах можно делать даже так: lea eax, [ebx + 4*esi + 5] Команда lea вычисляет значение второго операнда и помещает его в указанный регистр. А mov в аналогичных случаях занесет в регистр значение из памяти по адресу, равному значению второго операнда. --------- Трудное - то, что можно сделать немедленно. Невозможное - то, для выполнения чего требуется немного больше времени |
Ответ отправил: Ayl (статус: Профессор) Отправлен: 28.06.2005, 13:24 |
Отвечает: Евгений Иванов Здравствуйте, Терсков Алексей Николаевич! LEA - вычисляет адрес эффективный. Возможны все методы адресации, которые применимы. MOV использует те же методы адресации, при этом тоже вычисляет эфф.адрес, и загружает оттуда значение. PSP применяется для хранения информации о разных параметрах и обмене ею с системой. командная строка, FCB, DTA и т.п. там хранятся. --------- Что имеем - не храним, потерявши - плачем |
Ответ отправил: Евгений Иванов (статус: Профессор) Отправлен: 28.06.2005, 13:46 |
Отвечает: Алексей Смуриков Здравствуйте, Терсков Алексей Николаевич! PSP это сектор данных, где содержится командная строка! |
Ответ отправил: Алексей Смуриков (статус: Студент) Отправлен: 28.06.2005, 18:07 |
Вопрос № 22.769 |
регистры процессора SI (Source Index) - индекс источника. DI (Destination Index) - индекс назначения. Кто-нибудь может обьяснить их назначение и на очень простом примере продеманстрировать их применение. |
Отправлен: 28.06.2005, 12:45 Вопрос задал: Терсков Алексей Николаевич (статус: Посетитель) Всего ответов отправлено: 2 |
Отвечает: DSota Здравствуйте, Терсков Алексей Николаевич! Это обычные регистры, индекс назначения и источника - это их дополнительные свойства, нужные при строчных операциях: Например: lodsb - выполняет "mov al,[ds:si];inc si" stosb - выполняет "mov [es:di],ax;inc di" movsb - выполняет "mov [es:di],[ds:si];inc di;inc si" Простой пример: скопировать 10 байтовую строку STR1 в str2: mov di,offset str2 mov si,offset str1 mov cx,10 rep movsb --------- Открыть глаза навстречу солнцу. |
Ответ отправил: DSota (статус: Практикант) Отправлен: 28.06.2005, 13:07 |
Отвечает: Евгений Иванов Здравствуйте, Терсков Алексей Николаевич! обычные регистры. делай с ними всё, что хочешь. но при этом они неявно присутствуют при командах работы со строками. MOVS, STOS, LODS.. вот, например, кусок кода из моей программы. есть таблица. оттуда нужно вырезать кусочек (объект, элемент). вот как это обычно происходит ;) это практика. готов к такому программированию? ;) это тебе не просто movsb,. чтобы добраться к ней, нужно ещё обвязку делать! mov eax, [TDlgVisible] or eax, eax jz @@m50 xchg esi, eax mov edi, esi mov eax, [esi] mov ecx, eax mov edx, eax or eax, eax jz @@m50 sub esi, 4 @m4: add esi, 8 mov eax, [esi] cmp eax, [idDlg] jz @@m30 dec ecx jnz @@m4 jmp @@m50 @m30: push edi add edi, 4 add esi, 8 dec ecx jecxz @@m30_0 shl ecx, 1 rep movsd @m30_0: pop edi lea eax, [edx-1] shl eax, 3 add eax, 4 Call GlobalReAlloc,edi,eax,GMEM_MOVEABLE or eax, eax jz @@m50 mov [TDlgVisible], eax xchg esi, eax mov eax, [esi] dec eax mov [esi], eax @m50: Удачи! Прикреплённый файл: Загрузить >> |
Ответ отправил: Евгений Иванов (статус: Профессор) Отправлен: 28.06.2005, 14:04 |
Вопрос № 22.770 |
Как правильно скомпилировать COM - файл в MASM 6.14 и TASM 4.1, что бы получить *.lst, *.obj, *.com Какие нужны параметры командной строки |
Отправлен: 28.06.2005, 12:51 Вопрос задал: Терсков Алексей Николаевич (статус: Посетитель) Всего ответов отправлено: 3 |
Отвечает: DSota Здравствуйте, Терсков Алексей Николаевич! В TASM 4.1: tasm /la myprog.asm tlink /t myprog.obj --------- Открыть глаза навстречу солнцу. |
Ответ отправил: DSota (статус: Практикант) Отправлен: 28.06.2005, 13:16 |
Отвечает: Евгений Иванов Здравствуйте, Терсков Алексей Николаевич! используй вот такой BAT-файл. Приложение: Прикреплённый файл: Загрузить >> |
Ответ отправил: Евгений Иванов (статус: Профессор) Отправлен: 28.06.2005, 13:43 |
Отвечает: ASMодей Здравствуйте, Терсков Алексей Николаевич! Для TASM уже сказали, а для MASM так: ml.exe /AT /Fl myprog.asm |
Ответ отправил: ASMодей (статус: Профессионал) Отправлен: 29.06.2005, 05:02 |
Вопрос № 22.774 |
У меня возник вопрос про сегмент стека. stack segment stack db 100 dup (?) stack ends assume ss:stack, cs:code, ds:data, es:data1 Почему для сегмента стека не нужно следующее: mov ax, stack mov ss, ax |
Отправлен: 28.06.2005, 13:45 Вопрос задал: Терсков Алексей Николаевич (статус: Посетитель) Всего ответов отправлено: 2 |
Отвечает: Евгений Иванов Здравствуйте, Терсков Алексей Николаевич! а потому что ты пишешь атрибут у сегмента - stack. это команда линкёру, чтобы добавить в заголовок EXE-файла информацию о стеке. и при запуске программы всё уже будет на месте. если бы ты не указывал атрибут stack, то тогда пришлось бы по ручному стек указывать. удачи! --------- Что имеем - не храним, потерявши - плачем |
Ответ отправил: Евгений Иванов (статус: Профессор) Отправлен: 28.06.2005, 13:54 |
Отвечает: Ayl Здравствуйте, Терсков Алексей Николаевич! Потому что определение сегмента стека имеет значение только для EXE-программы, а в заголовке EXE-программы прописываются начальные значения для SS и SP. Их туда записывает компилятор на основе определения сегмента стека и директивы привязки ASSUME. --------- Трудное - то, что можно сделать немедленно. Невозможное - то, для выполнения чего требуется немного больше времени |
Ответ отправил: Ayl (статус: Профессор) Отправлен: 28.06.2005, 16:34 |
Вопрос № 22.782 |
Вопрос такой: Какие сегменты можно определить в программе, которая будет преобразована в COM файл ? |
Отправлен: 28.06.2005, 15:35 Вопрос задал: Терсков Алексей Николаевич (статус: Посетитель) Всего ответов отправлено: 3 |
Отвечает: DSota Здравствуйте, Терсков Алексей Николаевич! Все сегменты, кроме сегмента стека... Linker их сам объединит в один. --------- Открыть глаза навстречу солнцу. |
Ответ отправил: DSota (статус: Практикант) Отправлен: 28.06.2005, 15:57 |
Отвечает: Евгений Иванов Здравствуйте, Терсков Алексей Николаевич! зависит от программы. если EXE-программу написать правильно, то преобразовать в COM можно одним махом. если же писать со всякими множественными сегментами, то это будет сделать невозможно. помню, делал преобразование из COM в EXE. http://superforest.narod.ru/research_coder.htm всё отлично работает. вот код в начале преобразованного EXE-файла стоит: emul_com: pushf pusha push ss pop es cld mov si,(len_emul+256) mov di,65024 push es push di mov cx,len_emul2 rep movsb retf start_emul: push ds pop es mov di,256 mov cx,0 ;# size_program: rep movsb popa popf push ds pop ss push 0 push ds push 256 retf len_emul = start_emul-emul_com len_emul2 = end_emul-start_emul Прикреплённый файл: Загрузить >> |
Ответ отправил: Евгений Иванов (статус: Профессор) Отправлен: 28.06.2005, 16:33 |
Отвечает: Ayl Здравствуйте, Терсков Алексей Николаевич! Сегмент кода и сегмент данных. Причем последний определять необязательно. Сегмент стека можно описать, но он точно будет проигнорирован либо компилятор ругнется. --------- Трудное - то, что можно сделать немедленно. Невозможное - то, для выполнения чего требуется немного больше времени |
Ответ отправил: Ayl (статус: Профессор) Отправлен: 28.06.2005, 16:36 |
Вопрос № 22.783 |
Определение стека в COM-файле отсутствует. Как ведет себя COM-файл с учетом этого обстоятельства? |
Отправлен: 28.06.2005, 15:38 Вопрос задал: Терсков Алексей Николаевич (статус: Посетитель) Всего ответов отправлено: 3 |
Отвечает: DSota Здравствуйте, Терсков Алексей Николаевич! При загрузке COM файла устанавливается: SS=CS, SP=0fffeh. --------- Открыть глаза навстречу солнцу. |
Ответ отправил: DSota (статус: Практикант) Отправлен: 28.06.2005, 15:55 |
Отвечает: Евгений Иванов Здравствуйте, Терсков Алексей Николаевич! стек не определён , потому что нет заголовка. но он подразумевается. CS=DS=SS SP=FFFEh то есть, самый конец сегмента. и растёт сверху вниз. добавка: в самом начале PSP стоит блок данных - CDh, 20h это команда INT 32. это сделано для того, чтобы можно было сделать ret и возвратиться в ДОС. Но при ret нужно следить, чтобы стек был нормализован. --------- Что имеем - не храним, потерявши - плачем |
Ответ отправил: Евгений Иванов (статус: Профессор) Отправлен: 28.06.2005, 16:22 |
Отвечает: Ayl Здравствуйте, Терсков Алексей Николаевич! Стек никогда не отсутствует. В крайнем случае есть стек ОС. В COM-программе под стек отводится вся память в сегменте программы, которая не занята программой и данными. В качестве сегмента стека устанавливается CS, в качестве указателя вершины - значение FFFEh. Но тебе ничего не мешает перенести стек куда хочешь. --------- Трудное - то, что можно сделать немедленно. Невозможное - то, для выполнения чего требуется немного больше времени |
Ответ отправил: Ayl (статус: Профессор) Отправлен: 28.06.2005, 16:41 |
Вопрос № 22.787 |
Я чего - то понять не могу, если CS=DS=SS sp=0fffe, то есть все в одной куче что ли ? допустим MOV AX, ffff MOV DS, AX то в стеке места не останится, ведь он растет в сторону уменьшения адресов. Выходит заполняя стек уменьшается смещение от DS и CS что-то я запутался на верно. Можно ли в исходный текс будующей программы типа *.COM определять упрощенные директивы ? или только в *.exe файлах ? |
Отправлен: 28.06.2005, 16:47 Вопрос задал: Терсков Алексей Николаевич (статус: Посетитель) Всего ответов отправлено: 3 |
Отвечает: Mad_C Здравствуйте, Терсков Алексей Николаевич! com-программе отводится лишь один сегмент для данных, кода и стека, поэтому и cs=ds=ss, соответственно, если ваш код будет интенсивно работать со стеком, то возможен вариант, что верхушка стека затрет часть кода или данных. |
Ответ отправил: Mad_C (статус: 1-ый класс) Отправлен: 28.06.2005, 16:56 |
Отвечает: Евгений Иванов Здравствуйте, Терсков Алексей Николаевич! когда работаешь со стеком. используется SP. стек никак не связан с сегментом DS. в COM-программе код, данные и стек в одном сегменте расположены. указатель стека SP - вверху этого сегмента. смотри вложение. там пример начала программы COM. Прикреплённый файл: Загрузить >> |
Ответ отправил: Евгений Иванов (статус: Профессор) Отправлен: 28.06.2005, 17:08 |
Отвечает: Ayl Здравствуйте, Терсков Алексей Николаевич! Конечно, в одной куче. Это же COM-программа, она занимает РОВНО один сегмент (64К). Это еще осталось от старых компов с ранними версиями DOS, для которых память 64К была очень большой (эх, было ж время!). Поэтому при старте программы регистры устанавливаются таким образом, чтобы указывать на один и тот же сегмент. Программа расположена с адреса 100h (перед ней - PSP), стек - в конце сегмента. Стек растет к началу сегмента, программа (теоретически) стационарна. Естесственно, если ты будешь сильно юзать стек и его не чистить, то рано или поздно они столкнутся и будет плохо. Но вряд ли ты напишешь что-нибудь килобайт на 30-40, и стек так использовать не будешь. Если только не захочешь какой-нибудь массивчик на 64 Кб. Ну в этом случае перенеси стек в другое место - и будет тебе счастье. Насчет упрощенных директив в COM-программах - да ради Бога! Используй. Они для того и предназначены. Только учти, что .DATA по умолчанию выравнивает сегмент на слово, т.ч. можешь приобрести лишний 1 байт :-) Кстати, вместе с упрощенными директивами можешь также пользоваться и директивой .StartUp. Она заменяет директиву ASSUME в начале программы и выполняет стандартные настроечные действия: для COM: прописывает ORG 100h для EXE: устанавливает DS на сегмент данных mov ax, @DATA mov ds, ax --------- Трудное - то, что можно сделать немедленно. Невозможное - то, для выполнения чего требуется немного больше времени |
Ответ отправил: Ayl (статус: Профессор) Отправлен: 28.06.2005, 17:37 |
Вопрос № 22.796 |
Передо мной задача такая: Нужно написать программу для вычисления 12 чисел Фибоначчи: 1,1,2,3,5,13,... Я чего - то вопроса непойму Фибоначчи - это число ряда чисел, т.е. массива или последовательности, представляющее собой сумму двух предыдущих. Это вы знаете все ! Подскажите мне пожалуйста я немогу вопроса понять. причем здесь цифра 13 там же "8" должна стоять а потом 13. Да при написании вопроса все понял. Наверно должно получиться вот так: 1.1.2.3.5.8.13.21.34.55.89.144 А как алгоритм описать ? В паскале нет проблем ! особенно в самом начале. С единицы чтоли начинать, или с двух единиц, а может с нуля? |
Отправлен: 28.06.2005, 18:39 Вопрос задал: Терсков Алексей Николаевич (статус: Посетитель) Всего ответов отправлено: 2 |
Отвечает: Ayl Здравствуйте, Терсков Алексей Николаевич! Ряд Фибоначчи определяется следующим образом: F(1) = F(2) = 1 F(n) = F(n-1) + F(n-2) для любого n >= 3, n - целое. Т.е. начинаешь с 2-х единиц. А насчет алгоритма - все просто. На каждом шаге итерации у тебя должны быть в работе F1 = F(n-1) и F2 = F(n-2). По ним ты определяешь F = F(n), после чего делаешь три присваивания: F2 := F1 F1 := F n := n + 1 Вначале F1 = F2 = 1 и n = 3. Продолжаешь, пока не не станет > 12. Тебе еще потребуется процедура вывода числа на экран. --------- Трудное - то, что можно сделать немедленно. Невозможное - то, для выполнения чего требуется немного больше времени |
Ответ отправил: Ayl (статус: Профессор) Отправлен: 28.06.2005, 18:54 |
Отвечает: Евгений Иванов Здравствуйте, Терсков Алексей Николаевич! mov ecx,12-3 sub eax,eax inc eax mov ebx,eax @m1: mov edx,eax add eax,ebx mov ebx,edx dec ecx jnz @@m1 --------- Что имеем - не храним, потерявши - плачем |
Ответ отправил: Евгений Иванов (статус: Профессор) Отправлен: 28.06.2005, 19:03 |
Вопрос № 22.801 |
Уважаемые программисты дайте ссылку если есть на какую - нибудь статью или литературу, где встречается Фибоначчи. Я считаю мне нужно ее прочесть. |
Отправлен: 28.06.2005, 20:21 Вопрос задал: Терсков Алексей Николаевич (статус: Посетитель) Всего ответов отправлено: 1 |
Отвечает: DSota Здравствуйте, Терсков Алексей Николаевич! Это самая первая ссылка из Гугла... Приложение: |
Ответ отправил: DSota (статус: Практикант) Отправлен: 29.06.2005, 10:29 |
Вопрос № 22.805 |
Уважаемый "Ayl" и все остальные Я совсем ничего незнаю о фибоначчи но по вашему алгоритму у меня почемуто получается. 1 1 3 5 7 9 11 13 Я что-то опять непонял. Должно же быть так: 1 1 2 3 5 8 и т.д. |
Отправлен: 28.06.2005, 20:37 Вопрос задал: Терсков Алексей Николаевич (статус: Посетитель) Всего ответов отправлено: 3 |
Отвечает: Евгений Иванов Здравствуйте, Терсков Алексей Николаевич! это у меня получается так? не думаю... mov ecx,12-3 sub eax,eax inc eax mov ebx,eax @m1: mov edx,eax add eax,ebx mov ebx,edx dec ecx jnz @@m1 ты этот код пробовал? mov esi, ofs a1 mov ecx,12-1 sub eax,eax inc eax mov ebx,eax mov [esi], eax @m1: add esi, 4 mov [esi], eax mov edx,eax add eax,ebx mov ebx,edx dec ecx jnz @@m1 mov esi, ofs a1 Call _wsprintfA C,ofs b0,ofs a2, [ww esi], [ww esi+4], [ww esi+8], [ww esi+12], [ww esi+16], [ww esi+20], [ww esi+24], [ww esi+28], [ww esi+32], [ww esi+36], [ww esi+40], [ww esi+44] Call MessageBox,0,ofs b0,ofs b0,MB_ICONEXCLAMATION ;! b0 db 64 dup('_'), 0 a1 dd 16 dup(0) a2 db '%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u', 0 --------- Что имеем - не храним, потерявши - плачем |
Ответ отправил: Евгений Иванов (статус: Профессор) Отправлен: 28.06.2005, 21:30 |
Отвечает: Ayl Здравствуйте, Терсков Алексей Николаевич! Значит, что-то неправильно делаешь. Вот цикл расчета последовательности: mov ax, 1 ; В AX будем хранить F (n-2) mov bx, 1 ; В BX будем хранить F (n-1) mov cx, 12 - 2 ; В CX - кол-во членов последовательности, требуемых для вывода @loop: add ax, bx ; AX = F (n) = F (n-2) + F (n-1) = AX + BX call Print_AX ; Вызываем процедуру вывода числа из AX на экран xchg ax, bx ; Обмениваем регистры AX и BX. Теперь AX = F (n-1), BX = F (n), что на следующей итерации превратится (т.к. n = n + 1) в F (n-2) и F (n-1). loop @@loop Все. --------- Трудное - то, что можно сделать немедленно. Невозможное - то, для выполнения чего требуется немного больше времени |
Ответ отправил: Ayl (статус: Профессор) Отправлен: 29.06.2005, 10:51 |
Отвечает: DSota Здравствуйте, Терсков Алексей Николаевич! Чуть короче алгоритм - разобраться легче... Приложение: |
Ответ отправил: DSota (статус: Практикант) Отправлен: 29.06.2005, 11:04 |
© 2001-2005, RusFAQ.ru, Россия, Москва. Все права защищены.
Идея, дизайн, программирование, авторское право: Калашников О.А.
Subscribe.Ru
Поддержка подписчиков
Другие рассылки этой тематики
Другие рассылки этого автора
Подписан адрес:
Код этой рассылки:
comp.soft.prog.faq
Отписаться
Вспомнить пароль
В избранное | ||