Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.144.151.106] |
|
Сообщ.
#1
,
|
|
|
Встроенный ассемблер Я думаю, что все, кто хоть немного знаком с Турбо Паскалем, знают, что в нем есть такая хитрая штука, которая называется встроенным ассемблером, но далеко не все новички умеют им работать. Встроенный ассемблер (далее - просто ассемблер) дает возможность программировать на уровне отдельных машинных инструкций. Это - главное отличие ассемблера от Паскаля и в этом отличии сосредоточены все его достоинства и недостатки. Достоинство заключается в том, что, программируя на ассемблере, программист обычно выбирает последовательность машинных инструкций так, чтобы реализовать нужные вычисления с максимальной скоростью при минимальных затратах памяти, в то время как даже такой весьма совершенный компилятор, как Турбо Паскаль, неизбежно вносит в машинный код некоторую избыточность, уменьшающую скорость счета и увеличивающую затраты памяти. С другой стороны, программирование на уровне машинных инструкций - чрезвычайно хлопотное занятие и не может сравниться по скорости разработки программ с программированием на Паскале - в этом заключается главный недостаток ассемблера. Ассемблерные инструкции пишутся примерно так: program program_name; begin ... asm ... {Здесь располагаются ассемблерные инструкции} end; ... end. Операторы asm...end работают, как операндные скобки begin...end. т.е. можно делать так: for i := 1 to 100 do asm ... end; и так: if ((i=0) and (k<>6)) or (t div 5 - 7 = 99)) xor (r=0) then asm ... end; Регистры В Турбо Паскале (вернее в МП 8086/8088) имеется 14 регистров. Их можно поделить на 5 групп: Теперь подробнее: AX,BX,CX,DX можно использовать как переменные. CS, DS, SS, ES используются для указания сегмента. В частности CS - Содержит номер сегмента памяти (сегмента кода), в котором располагается текущая машинная инструкция DS - Содержит номер сегмента памяти (сегмента данных), в котором располагаются данные (константы и переменные) SS - Это сегмент Стека, а ES это... это дополнительный сегментный регистр, который используется для межсегментного обмена данными и в некоторых строковых операциях SP - Указывает на вершину стека. Совместно с регистром SS он адресует ячейку, куда будет помещаться/извлекаться операнд. BP - т.н. указатель базы. Облегчает создание и использование локального стека. IP - Определяет смещение относительно начала сегмента кода CS очередной исполняемой машинной инструкции. Содержимое IP автоматически изменяется в ходе исполнения инструкции, обеспечивая правильный порядок выборки команд из памяти. SI - Определяет адрес источника информации при индексной адресации данных. По умолчанию используется в паре с DS. DI - определяет приемник информации при межсегментном обмене данными. По умолчанию - в паре с ES. Команды. Ниже приведены команды, которые используются при использовании встроенного Ассемблера. Команды пересылки данных MOV - Переслать значение. push - "Загнать" в стек pop - Извлечь из стека xchg - Обменять значения mov, xchg нельзя использовать для пересылки из памяти в память: var a,b:integer; begin ... asm mov a,b {Ошибка!!!} { Надо так:} mov ax,b mov a,ax end; ... end; Вот пример. (В комментариях - код на Паскале, чтобы было легче разобраться) asm mov ax,60 {ax := 60} push ax mov bx,88 {bx := 88} mov ax,bx {ax := bx} pop ax {!!!ax := 60!!!} xchg ax,bx {ax = 60, bx = 88 -> ax = 88, bx = 60} end; Арифметические команды. ADD Сложить ADC Сложить, добавить перенос INC Увеличить на единицу SUB Вычесть SBB Вычесть с заёмом DEC Уменьшить на единицу MUL Умножить iMUL Умножить со знаком DIV Поделить iDIV Поделить со знаком Вот пример - программа выполняющая над двумя числами 4 арифметические операции program asm_test_arifnetika; var a,b,c:integer; begin ReadLn(a,b); asm mov ax,a {ax := a} adc ax,b {ax := ax+b} mov c,ax {c := ax} end; WriteLn('Сумма a и b = ',c); asm mov ax,a {ax := a} sbb ax,b {ax := ax - b} mov c,ax {c := ax} end; WriteLn('Разность a и b = ',c); asm mov ax,a {ax := a} imul ax,b {ax := ax*b} mov c,ax {c := ax} end; WriteLn('Произведение a и b = ',c); asm mov ax,a {ax := a} idiv ax,b {ax := ax div b} mov c,ax {c := ax} end; WriteLn('Частное a и b = ',c) end; Вот. Теперь... Битовые команды: and or xor not shl shr {and, и все остальные бинарные команды в ассемблере работают не совсем так, как в Паскале, а именно:} asm and ax,bx {будет означать ax := ax and bx} end; Условия. Синтаксис написания условий в ассемблере значительно отличается от Паскаля. Попробую объяснить что и как. Думаю, что легче всего на примере. Программа (вернее её фрагмент) гениален. Она выполняет if a=0 then b := 7; Примерно так это бужет выглядеть на асме asm cmp a,0 {?a=0?} jne @ {нет - перейти к концу} mov b,7 {b := 7} @: end; Вот. Сначала идет оператор cmp и два сравниваемых параметра через запятую. На следующей строчке идет параметр сравнения. В данном случае он расшифровывается как перейти, если не равны. Вот все параметры условий: Операция больше: JA - для беззнаковых чисел JG - для чисел со знаком Числа равны - JE Операция меньше: JB - для беззнаковых чисел JL - для чисел со знаком Операция больше или равно: JAE - для беззнаковых чисел JGE - для чисел со знаком Операция меньше или равно: JBE - для беззнаковых чисел JLE - для чисел со знаком Не равно - JNE Новички часто путаются с написанием условий на ассемблере т.к. логика при их написании должна быть совсем другая. Прерывания. Здесь уж совсем все просто. Ниже приводится пример выводящий курсор мыши на экран. asm mov ax,01h {ax := 1} int 33h {33h - прерывание мышки} end; |
Сообщ.
#2
,
|
|
|
Цитата Азат @ 13.12.04, 15:35 Здесь уж совсем все просто. Ниже приводится пример выводящий курсор мыши на экран. asm mov ax,01h {ax := 1} int 33h {33h - прерывание мышки} end; Я бы сделал вот так: BEGIN Asm MOV AX,11h {ставим графику} INT 10h MOV AX,00h {инициализируем мышку} INT 33h MOV AX,01h {показываем мышку} INT 33h @LOOP: {балуемся - бесконечный цикл} JMP @LOOP End END. |
Сообщ.
#3
,
|
|
|
Ассемблерные процедуры.
Синтаксис. procedure названиепроцедуры(параметры); assembler; asm ... end; например: procedure ShowMouse; assembler; asm mov ax,01h int 33h end; Ассемблерные функции. Синтаксис: function названиефункции(параметры):значение; assembler; asm ... end; Результат функции записывается в регистры. А именно: Пример: function Shogen(a,b:integer):integer; assembler; asm mov ax,a adс ax,b end; Литература Фаронов В. В. Турбо паскаль: начальный курс Форум на исходниках |