![]() |
Страницы: (17) Все « Первая ... 4 5 [6] 7 8 ... Последняя »
( Перейти к первому непрочитанному сообщению ) |
![]() ![]() ![]() |
|
Chingachguk |
|
||||||
Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1232 Регистрация: 25.3.2002 Где: Москва Репутация: 11 Всего: 18 |
Нет, дело не в этом ;) Смотри, я вернул почти все к тому варианту, который был у тебя:
Разница - в двух командах.
Все абсолютно верно ! -------------------- I don't like the drugs (but the drugs like me). M.Manson. |
||||||
|
|||||||
Shuricksoft as a guest |
|
|||
Unregistered |
О, всё, я понял свою ошибку =)
Кстати, заодно, если тебе не сложно, приведи, пожалуйста, все известные тебе версии команды jmp с описанием (ну, jnz, jb, jbe - это понятно, а ещё какие?). Это хорошо, что верно =) Продолжаем? ![]() |
|||
|
||||
Mura-vey |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 22.4.2003 Репутация: нет Всего: нет |
Chingachguk Я внимательно ознакомился с уроками, задания правда не делал, но обязательно попробую как будет время.
Теперь самый каверзный вопрос: Как связать паскаль и ассемблер ? Сколько не пытался не получалось. Надо что бы просто и доступно было. Это сообщение отредактировал(а) Mura-vey - 22.9.2003, 00:48 |
|||
|
||||
Monty |
|
|||
![]() Advanced Lamer ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3511 Регистрация: 3.4.2003 Где: Гваделупа Репутация: нет Всего: 27 |
Можно так
![]() Это сообщение отредактировал(а) Monty - 22.9.2003, 01:29 -------------------- ... О, вещая моя печаль, О, тихая моя свобода И неживого небосвода Всегда смеющийся хрусталь! |
|||
|
||||
Chingachguk |
|
||||||||||||||
Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1232 Регистрация: 25.3.2002 Где: Москва Репутация: 11 Всего: 18 |
Ну я не думаю, что имеет смысл приводить кусок справочника или руководство от интела. Наоборот, моя концепция изучения такова: пытаемся что-то сделать -> появляется мысль -> как я могу ее реализовать ? -> мне нужна такая-то команда -> она есть ? -> есть, отлично. Использую ее сейчас, да и на будущее запомню. В общем и целом все команды сравнения основываются вот на чем: для сравнения чего бы то ни было процессор использует сложение (вычитание - это тоже сложение). Сложение двоичных счетчиков. На основании результата модифицируется так называемый регистр флагов - вспомогательный регистр процессора. Все команды сравнения используют этот регистр для анализа. Например, мы хотим проверять, вышли ли мы за пределы размерности байтовой переменной при сложении регистров AL и AH:
Требуемая логика: так как в регистре al 8 бит, то максимум, который может быть в нем - это число 255 (без знака) (или 0xFF или $FF или 011111111b или...). При сложении 10 и 10 в al будет 20, при сложении 100 и 100 - 200, при сложении 254 и 1 будет 255, а вот если сложить 255 и 1, то будет 0. Напоминаю, процессор складывает регистры как двоичные счетчики (типа связанных в цепочку триггеров) без насыщения, те если все биты (триггеры) в состоянии 1, то следующий добавляющий импульс последовательно сбросит все биты в 0. Так вот, нам нужно знать, когда произошел такой вот переход (те сумма Value1+Value2 > 255):
Как это сделать ? Есть такой факт, что процессор контролирует факт переноса (перехода через максимальное значение) устанавливая в определенное состояние определенный бит регистра флагов. Этот бит имеет название CF (Carry Flag). Таким образом, после сложения можно опереться на этот факт:
Команда jnc как раз проверяет, установлен ли флаг CF. Точнее говоря, она проверяет его состояние (я не помню, 0 или 1 является признаком переноса). На таких вот изменениях регистра флагов и основаны все команды условных переходов. В регистре флагов несколко таких флажков.
Да, вот как раз про флаги заговорили. Давай уж на них немного остановимся. Попробуй поизучать влияние различных команд сложения или вычитания на регистр флагов. Первые 8 бит регистра флагов можно получить командой:
Попробуй вывести состояние регистра флагов. Если сможешь, понаблюдай за тем, как он меняется после различных команд сложения, вычитания... и т.п. Поиграйся с ним, короче ;)
Гм, я как раз тут об этом все время говорю. Попробуй задать конкретный вопрос ;) Например: как мне сложить две пас-переменные с помощью ассемблера или как мне написать функцию на ассемблере, получающую указатель на массив WORD'ов и сортирующую его и т.п. -------------------- I don't like the drugs (but the drugs like me). M.Manson. |
||||||||||||||
|
|||||||||||||||
Mura-vey |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 22.4.2003 Репутация: нет Всего: нет |
Хорошо, тогда задачка такая. На паскале мы вводим одномерный массив А[1000] и сортируем его на ассемблере, а выводим снова в паскале.
|
|||
|
||||
Mura-vey |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 22.4.2003 Репутация: нет Всего: нет |
Разумеется прога сортирования написана отдельно! Полученый обж мы должны слинковать с прогой на паскале.
|
|||
|
||||
Shuricksoft as a guest |
|
|||
Unregistered |
По поводу регистра флагов нашёл, что за перенос отвечает младший (самый правый =) ) бит. 0 - переноса нет, 1 - есть. Потом нашёл в отладчике, где отображается этот регистр =) Там нашёл ZF, принимающий значение 1, если результат сравнения "равно" и 0, если "не равно". Больше ничего толком не понял. Там есть ещё что-то интересное? =) Кстати, не уловил, где "больше-меньше" указывается? Или это проверяет сам компилятор вычитанием?
|
|||
|
||||
Chingachguk |
|
||||||
Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1232 Регистрация: 25.3.2002 Где: Москва Репутация: 11 Всего: 18 |
Сначала по поводу вызова асм-кода. Этот код помещаем в файл sort_bub.asm и компиллируем:
masm sort_bub Должен получится файл sort_bub.obj Теперь паскаль:
Но я предпочитаю не размещать асм-код в отдельных файлах, а писать его в асм-вставках в теле паскалевских программ. -------------------- I don't like the drugs (but the drugs like me). M.Manson. |
||||||
|
|||||||
Chingachguk |
|
||||||||||
Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1232 Регистрация: 25.3.2002 Где: Москва Репутация: 11 Всего: 18 |
С помощью lahf ? Если так, то ты выполнил "задание" !
А пока особо ничего и не надо ;) Я же говорю - при решении конкретной задачи возникает необходимость чего-либо, тогда и узнаешь все досконально. В данном случае регистр флагов - это "самый нижний" уровень, доступный программисту. А не команды условных переходов. Ведь, изучая ассмеблер, стремишься добратся до "самого основания", пуркуа па ? То, что ты обратил внимание на существование отладчика - хорошо !
Нет, компиллятор ничего не делает. Он просто втыкает команды, причем не всегда удачно. Попробуй разобраться, как выполняются команды условных переходов из серии "больше-меньше". Приведу их примеры:
Попробуй сравнить таким образом разные аргументы, понаблюдай за флагами. А вот и задание (достаточно сложное !). Пусть есть команда сравнения AX и BX и условный переход после:
Требуется: инвертирование результата сравнения после команды cmp ax,bx после команды cmp и перед командой jb (выделено <...>). Что имеется в виду ? Допустим, если ax=10, а bx=300, то результат будет "меньше". Необходимо сделать его "больше или равно", чтобы команда jb получила его (в регистре флагов - а где еще ?). Если же результат сравнения будет "больше или равно", то нужно сделать его "меньше". Для выполнения задания требуется команда загрузки регистра флагов значением. Этой командой может быть sahf - загрузить регистр флагов из регистра ah или popf (из стека). Честно говоря, я это задание выдумал тока что, не проверяя его реализуемость. Но я думаю, все будет хорошо ;) -------------------- I don't like the drugs (but the drugs like me). M.Manson. |
||||||||||
|
|||||||||||
Shuricksoft as a guest |
|
|||
Unregistered |
Да, с помощью lahf
Ну, я имел в виду, что компилятор суёт команды вычитания, то есть, программа проверяет, засунутыми командами. Вычисляет разность, проверяет флаг переноса и дальше реагирует, как ей надо. Предыдущая гипотеза подтверждается тем, что, как я обнаружил, за меньше-больше тоже отвечает флаг переноса... Если 1 - меньше, если 0 - больше. Ну, а за "равно", судя по всему, отвечает четвёртый слева бит. Задание я понял. Идея тоже есть. Но не могу осуществить, пока не узнаю, как получить доступ к отдельно взятому биту регистра... Ломал голову довольно долго, да решил у тебя спросить =) Ну, никак не могу понять, как инвертировать в регистре один-единственный (ну, или, в нашем случае, два) бит... |
|||
|
||||
Chingachguk |
|
||||||||
Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1232 Регистрация: 25.3.2002 Где: Москва Репутация: 11 Всего: 18 |
Если ты писал на СИ (а ведь писал, не так ли ?), то должен был видеть вот такие операторы: "^","|","&","~". Это так называемые битовые операторы: xor, or, and, not... Естественно, они есть и в ассемблере. Только работать с битами на нем гораздо легче ;) Набор команд больше и они гибче:
Легче потому, что в асме команд для битов больше и они гибче. Это и понятно - ассемблерный код должен уметь заставить процессор делать все, что тот умеет, а процессор работает также и с битами. Например, в языках высокого уровня нет команды test. Обычно для проверки битов пишут что-то вроде:
Но ведь можно написать:
Вот так ![]() -------------------- I don't like the drugs (but the drugs like me). M.Manson. |
||||||||
|
|||||||||
Shuricksoft as a guest |
|
|||
Unregistered |
На Си я писал довольно мало. В основном, на Паскале. And, or, xor, not я видел, но не знал, что они делают :-/ Поэкспериментировав, пришёл к выводу, что xor ax,i инвертирует i-тый бит регистра ах; and ax,i устанавливает туда 0; or ax,i - устанавливает 1; not ax инвертирует все биты. Все это установил на основе экспериментов, так что если я что-то понял неправильно, поправь меня, плз =)
Таким образом, получается вот такой код там, где <...>
Этот код на "ура" меняет больше на меньше и наоборот. Несколько по-другому дело обстоит с "равно". В данном примере (приведённом тобой коде) такой фокус работает. Но если проверять через je или jne, то получается, что ни один бит (после неудачных попыток определить, какой нам нужен, проверял все подряд) при инвертировании не инвертирует результат :-/ Почему так? |
|||
|
||||
Shuricksoft |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 177 Регистрация: 27.3.2002 Где: Odessa, Ukraine Репутация: нет Всего: нет |
Я вчера ночью перед сном разобрался с and, or и xor, так что предыдущую версию этого поста считать недействительной =)
Но просьба в силе: приведи, плз, паскалевский эквивалент value&(1<<i). Остальное понял, а вот что значит два знака << и почему это в скобках - неясно =) А рабочий код, работающий с "равно", приведу чуть позже =) Это сообщение отредактировал(а) Shuricksoft - 5.10.2003, 19:29 |
|||
|
||||
Shuricksoft |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 177 Регистрация: 27.3.2002 Где: Odessa, Ukraine Репутация: нет Всего: нет |
Вот этот код, с виду, работает. Инвертирует значение флага равенства и флага "больше-меньше". Можно, конечно, проверять, надо ли нам инвертировать флаг равенстсва, но к изменению результата это не приведёт, а код увеличит, уменьшив быстродействие =)
|
|||
|
||||
![]() ![]() ![]() |
Правила форума "Asm для начинающих" | |
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, MAKCim. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Asm для начинающих | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |