Поиск:

Ответ в темуСоздание новой темы Создание опроса
> ASM - с чего начать? 
:(
    Опции темы
Chingachguk
Дата 19.9.2003, 08:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1232
Регистрация: 25.3.2002
Где: Москва

Репутация: 11
Всего: 18



Цитата

По-моему, единственная разница при выполнении новой версии кода - это то, что при окончании цкла значение IndX или У = MyScreenBarSize + 1 (у меня - просто MyScreenBarSize). Цикл же выполняется для одинаковых значений в обоих случаях. Но ведь Паскалевское for IndX := 1 to MyScreenBarSize в конце тоже выдаст MyScreenBarSizr (без 1). Я что-то совсем запутался :-/


Нет, дело не в этом ;) Смотри, я вернул почти все к тому варианту, который был у тебя:

Цитата

  { Цикл опроса клавиатуры ~ repeat until keypressed }
  repeat
    { Рисуем квадрат размером MyScreenBarSize с центром в MyScreenCenter }
    asm
    mov al,MyScreenColor
    mov CurrColor,al
    mov IndY,0
@@YCycle:
        inc IndY
        mov IndX,0
@@XCycle:
        inc IndX
        mov ax,MyScreenCenter
        mov CurrCoordinate,ax
        mov ax,IndY
        push cx
        mov cx,320
        mul cx
        pop cx
        add CurrCoordinate,ax
        mov ax,IndX
        add CurrCoordinate,ax
        mov ax,0A000h
        mov es,ax
        mov bx,ds:CurrCoordinate
        mov al,CurrColor
        mov byte ptr es:[bx],al
        mov ax,MyScreenBarSize
        cmp IndX,ax
        jb  @@XCycle
        mov ax,MyScreenBarSize
        cmp IndY,ax
        jb  @@YCycle
    inc MyScreenBarSize
    end;

    { Если размер стал более чем MaxBarSize }
    if MyScreenBarSize>=MaxBarSize then MyScreenBarSize:=1;
    { Проверяем кейбоард }
  until keypressed;


Разница - в двух командах.

Цитата

По поводу оптимизации, пользуясь твоей подсказкой, вынес строки
mov ax,0A000h
mov es,ax
непосредственно перед началом циклов. Больше ничего сделать не смог.


Все абсолютно верно !


--------------------
I don't like the drugs (but the drugs like me). M.Manson.
PM MAIL ICQ   Вверх
Shuricksoft as a guest
Дата 20.9.2003, 11:54 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











О, всё, я понял свою ошибку =)
Кстати, заодно, если тебе не сложно, приведи, пожалуйста, все известные тебе версии команды jmp с описанием (ну, jnz, jb, jbe - это понятно, а ещё какие?).
Это хорошо, что верно =) Продолжаем? wink.gif
  Вверх
Mura-vey
  Дата 22.9.2003, 00:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 45
Регистрация: 22.4.2003

Репутация: нет
Всего: нет



Chingachguk Я внимательно ознакомился с уроками, задания правда не делал, но обязательно попробую как будет время.

Теперь самый каверзный вопрос: Как связать паскаль и ассемблер ? Сколько не пытался не получалось. Надо что бы просто и доступно было.

Это сообщение отредактировал(а) Mura-vey - 22.9.2003, 00:48
PM MAIL   Вверх
Monty
  Дата 22.9.2003, 01:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Advanced Lamer
****


Профиль
Группа: Участник Клуба
Сообщений: 3511
Регистрация: 3.4.2003
Где: Гваделупа

Репутация: нет
Всего: 27



Можно так
Код
..........
var
I, J: integer;
begin
 I := 22;
 asm
   mov J, I
   add J, 11
   xor I, I
 end;
//посмотри теперь на значение переменных, это только самое простое
...............
end;

smile.gif

Это сообщение отредактировал(а) Monty - 22.9.2003, 01:29


--------------------
...
О, вещая моя печаль,
О, тихая моя свобода
И неживого небосвода
Всегда смеющийся хрусталь!
PM MAIL ICQ   Вверх
Chingachguk
Дата 22.9.2003, 15:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1232
Регистрация: 25.3.2002
Где: Москва

Репутация: 11
Всего: 18



Цитата
Кстати, заодно, если тебе не сложно, приведи, пожалуйста, все известные тебе версии команды jmp с описанием (ну, jnz, jb, jbe - это понятно, а ещё какие?).


Ну я не думаю, что имеет смысл приводить кусок справочника или руководство от интела. Наоборот, моя концепция изучения такова: пытаемся что-то сделать -> появляется мысль -> как я могу ее реализовать ?
-> мне нужна такая-то команда -> она есть ? -> есть, отлично. Использую ее сейчас, да и на будущее запомню.

В общем и целом все команды сравнения основываются вот на чем: для сравнения чего бы то ни было процессор использует сложение (вычитание - это тоже сложение). Сложение двоичных счетчиков. На основании результата модифицируется так называемый регистр флагов - вспомогательный регистр процессора. Все команды сравнения используют этот регистр для анализа. Например, мы хотим проверять, вышли ли мы за пределы размерности байтовой переменной при сложении регистров AL и AH:

Цитата

mov  al,Value1
mov  ah,Value2

add  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):

Цитата

mov  al,Value1
mov  ah,Value2

add  al,ah
; IF (AL+AH>255) THEN ... ELSE ...


Как это сделать ? Есть такой факт, что процессор контролирует факт переноса (перехода через максимальное значение) устанавливая в определенное состояние определенный бит регистра флагов. Этот бит имеет название CF (Carry Flag). Таким образом, после сложения можно опереться на этот факт:

Цитата

mov  al,Value1
mov  ah,Value2

add  al,ah
jnc @@Then ; Jump if not carry
@@Else:
; ...
@@Then:
; ...


Команда jnc как раз проверяет, установлен ли флаг CF. Точнее говоря, она проверяет его состояние (я не помню, 0 или 1 является признаком переноса).

На таких вот изменениях регистра флагов и основаны все команды условных переходов. В регистре флагов несколко таких флажков.

Цитата
Продолжаем? 


Да, вот как раз про флаги заговорили. Давай уж на них немного остановимся.
Попробуй поизучать влияние различных команд сложения или вычитания на регистр флагов. Первые 8 бит регистра флагов можно получить командой:

Цитата
LAHF ; Load to AH register FLAGS


Попробуй вывести состояние регистра флагов. Если сможешь, понаблюдай за тем, как он меняется после различных команд сложения, вычитания... и т.п. Поиграйся с ним, короче ;)

Цитата
Теперь самый каверзный вопрос: Как связать паскаль и ассемблер ? Сколько не пытался не получалось. Надо что бы просто и доступно было


Гм, я как раз тут об этом все время говорю. Попробуй задать конкретный вопрос ;) Например: как мне сложить две пас-переменные с помощью ассемблера или как мне написать функцию на ассемблере, получающую указатель на массив WORD'ов и сортирующую его и т.п.


--------------------
I don't like the drugs (but the drugs like me). M.Manson.
PM MAIL ICQ   Вверх
Mura-vey
Дата 23.9.2003, 17:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 45
Регистрация: 22.4.2003

Репутация: нет
Всего: нет



Хорошо, тогда задачка такая. На паскале мы вводим одномерный массив А[1000] и сортируем его на ассемблере, а выводим снова в паскале.
PM MAIL   Вверх
Mura-vey
Дата 23.9.2003, 17:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 45
Регистрация: 22.4.2003

Репутация: нет
Всего: нет



Разумеется прога сортирования написана отдельно! Полученый обж мы должны слинковать с прогой на паскале.
PM MAIL   Вверх
Shuricksoft as a guest
Дата 23.9.2003, 21:37 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











По поводу регистра флагов нашёл, что за перенос отвечает младший (самый правый =) ) бит. 0 - переноса нет, 1 - есть. Потом нашёл в отладчике, где отображается этот регистр =) Там нашёл ZF, принимающий значение 1, если результат сравнения "равно" и 0, если "не равно". Больше ничего толком не понял. Там есть ещё что-то интересное? =) Кстати, не уловил, где "больше-меньше" указывается? Или это проверяет сам компилятор вычитанием?
  Вверх
Chingachguk
Дата 27.9.2003, 16:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1232
Регистрация: 25.3.2002
Где: Москва

Репутация: 11
Всего: 18



Цитата
Хорошо, тогда задачка такая. На паскале мы вводим одномерный массив А[1000] и сортируем его на ассемблере, а выводим снова в паскале.


Сначала по поводу вызова асм-кода.

Этот код помещаем в файл sort_bub.asm и компиллируем:

Цитата

CODE SEGMENT BYTE PUBLIC
      ASSUME CS:CODE
      PUBLIC  Sort_Bubble
Sort_Bubble PROC NEAR
  push bp
  mov  bp,sp
  mov  cx,[bp+4] ; Len of massive
  dec  cx
  jz  @@SortBubbleDone
@@SortBubble:
  push cx
  mov  si,[bp+6] ; Address of massive
@@OneStep:
  mov  ax,[si]
  cmp  word ptr [si+2],ax
  jae  @@NextElemNoLow
  xchg [si+2],ax
  mov  [si],ax
@@NextElemNoLow:
  inc  si
  inc  si
  loop @@OneStep
  pop  cx
  loop @@SortBubble
@@SortBubbleDone:
  pop  bp
  RET  2*2
Sort_Bubble ENDP
CODE  ENDS


masm sort_bub

Должен получится файл sort_bub.obj

Теперь паскаль:

Цитата

const
  MyMasLen = 10;
var
  MyMas: array[1..MyMasLen] of word;
  i: word;
{$L sort_bub.obj}
procedure Sort_Bubble(MasOffset,MasLen: Word); external;
begin
  randomize;
  write('Mas before:');
  for i:=1 to MyMasLen do
    begin
      MyMas[i]:=random(10);
      write(' ',MyMas[i]);
    end;
  writeln;
  Sort_Bubble(ofs(MyMas),MyMasLen);
  write('Mas after :');
  for i:=1 to MyMasLen do write(' ',MyMas[i]);
  writeln;
  readln;
end.


Но я предпочитаю не размещать асм-код в отдельных файлах, а писать его в асм-вставках в теле паскалевских программ.


--------------------
I don't like the drugs (but the drugs like me). M.Manson.
PM MAIL ICQ   Вверх
Chingachguk
Дата 27.9.2003, 16:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1232
Регистрация: 25.3.2002
Где: Москва

Репутация: 11
Всего: 18



Цитата
По поводу регистра флагов нашёл, что за перенос отвечает младший (самый правый =) ) бит. 0 - переноса нет, 1 - есть.


С помощью lahf ? Если так, то ты выполнил "задание" !

Цитата

Потом нашёл в отладчике, где отображается этот регистр =) Там нашёл ZF, принимающий значение 1, если результат сравнения "равно" и 0, если "не равно". Больше ничего толком не понял.


А пока особо ничего и не надо ;) Я же говорю - при решении конкретной задачи возникает необходимость чего-либо, тогда и узнаешь все досконально. В данном случае регистр флагов - это "самый нижний" уровень, доступный программисту. А не команды условных переходов. Ведь, изучая ассмеблер, стремишься добратся до "самого основания", пуркуа па ?

То, что ты обратил внимание на существование отладчика - хорошо !

Цитата

Там есть ещё что-то интересное? =) Кстати, не уловил, где "больше-меньше" указывается? Или это проверяет сам компилятор вычитанием?


Нет, компиллятор ничего не делает. Он просто втыкает команды, причем не всегда удачно.

Попробуй разобраться, как выполняются команды условных переходов из серии "больше-меньше". Приведу их примеры:

Цитата

cmp ax,bx
jb @AXLowThanBX ; jump if below

cmp ax,bx
ja @AXGreatThanBX ; jump if above

cmp ax,bx
jbe @AXLowOrEqualThanBX ; jump if below or equal


Попробуй сравнить таким образом разные аргументы, понаблюдай за флагами.

А вот и задание (достаточно сложное !). Пусть есть команда сравнения AX и BX и условный переход после:

Цитата

cmp ax,bx
; <...>
jb @AXLowThanBX ; jump if below


Требуется: инвертирование результата сравнения после команды 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.
PM MAIL ICQ   Вверх
Shuricksoft as a guest
Дата 30.9.2003, 15:24 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Да, с помощью lahf
Цитата
Нет, компиллятор ничего не делает. Он просто втыкает команды, причем не всегда удачно.

Ну, я имел в виду, что компилятор суёт команды вычитания, то есть, программа проверяет, засунутыми командами. Вычисляет разность, проверяет флаг переноса и дальше реагирует, как ей надо.
Предыдущая гипотеза подтверждается тем, что, как я обнаружил, за меньше-больше тоже отвечает флаг переноса... Если 1 - меньше, если 0 - больше. Ну, а за "равно", судя по всему, отвечает четвёртый слева бит.
Задание я понял. Идея тоже есть. Но не могу осуществить, пока не узнаю, как получить доступ к отдельно взятому биту регистра... Ломал голову довольно долго, да решил у тебя спросить =) Ну, никак не могу понять, как инвертировать в регистре один-единственный (ну, или, в нашем случае, два) бит...
  Вверх
Chingachguk
Дата 3.10.2003, 22:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1232
Регистрация: 25.3.2002
Где: Москва

Репутация: 11
Всего: 18



Цитата
Но не могу осуществить, пока не узнаю, как получить доступ к отдельно взятому биту регистра... Ломал голову довольно долго, да решил у тебя спросить =) Ну, никак не могу понять, как инвертировать в регистре один-единственный (ну, или, в нашем случае, два) бит...


Если ты писал на СИ (а ведь писал, не так ли ?), то должен был видеть вот такие операторы: "^","|","&","~". Это так называемые битовые операторы: xor, or, and, not...

Естественно, они есть и в ассемблере. Только работать с битами на нем гораздо легче ;) Набор команд больше и они гибче:

Цитата

xor  ax,22h ; ax ^ = 22h
or    bl,11h  ; bl| = 11h
and byte ptr es:[bx+di+22h],7 ; AND Память в es:[bx+di+22h] с 7
...
; И так далее


Легче потому, что в асме команд для битов больше и они гибче. Это и понятно - ассемблерный код должен уметь заставить процессор делать все, что тот умеет, а процессор работает также и с битами.

Например, в языках высокого уровня нет команды test. Обычно для проверки битов пишут что-то вроде:

Цитата

for (i=0;i<8;i++)
{
  if (value&(1<<i))
  {
    // Если i-ый бит установлен (не равен нулю)
  }
}


Но ведь можно написать:

Цитата

mov  cx,1
@@Cycle_i:
  test value,cx
  jz  @@BitNotSet
  ; Если i-ый бит установлен (не равен нулю)
@@BitNotSet:
  shl  cx,1 ; Сдвинуть бит налево (например, значение 4 перейдет в 8)
  cmp cx,100000000b ; Двоичная запись числа 256
  jb @@Cycle_i:


Вот так smile.gif


--------------------
I don't like the drugs (but the drugs like me). M.Manson.
PM MAIL ICQ   Вверх
Shuricksoft as a guest
Дата 4.10.2003, 22:35 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











На Си я писал довольно мало. В основном, на Паскале. And, or, xor, not я видел, но не знал, что они делают :-/ Поэкспериментировав, пришёл к выводу, что xor ax,i инвертирует i-тый бит регистра ах; and ax,i устанавливает туда 0; or ax,i - устанавливает 1; not ax инвертирует все биты. Все это установил на основе экспериментов, так что если я что-то понял неправильно, поправь меня, плз =)
Таким образом, получается вот такой код там, где <...>
Код

lahf
xor ah,1
sahf

Этот код на "ура" меняет больше на меньше и наоборот. Несколько по-другому дело обстоит с "равно". В данном примере (приведённом тобой коде) такой фокус работает. Но если проверять через je или jne, то получается, что ни один бит (после неудачных попыток определить, какой нам нужен, проверял все подряд) при инвертировании не инвертирует результат :-/ Почему так?
  Вверх
Shuricksoft
Дата 4.10.2003, 22:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 27.3.2002
Где: Odessa, Ukraine

Репутация: нет
Всего: нет



Я вчера ночью перед сном разобрался с and, or и xor, так что предыдущую версию этого поста считать недействительной =)
Но просьба в силе: приведи, плз, паскалевский эквивалент value&(1<<i). Остальное понял, а вот что значит два знака << и почему это в скобках - неясно =)
А рабочий код, работающий с "равно", приведу чуть позже =)

Это сообщение отредактировал(а) Shuricksoft - 5.10.2003, 19:29
PM MAIL ICQ   Вверх
Shuricksoft
Дата 5.10.2003, 21:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 27.3.2002
Где: Odessa, Ukraine

Репутация: нет
Всего: нет



Вот этот код, с виду, работает. Инвертирует значение флага равенства и флага "больше-меньше". Можно, конечно, проверять, надо ли нам инвертировать флаг равенстсва, но к изменению результата это не приведёт, а код увеличит, уменьшив быстродействие =)
Код

lahf
xor ah,01000001b
sahf

PM MAIL ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Asm для начинающих"
MAKCim
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой КОД.
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, MAKCim.

 
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Asm для начинающих | Следующая тема »


 




[ Время генерации скрипта: 0.0999 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.