PDA

Просмотр полной версии : Ассемблер. Нужна помощь.



orthodox
03.06.2009, 17:25
Надо на асме написать програмку вычисления функции

f=(a*2-3)*b+c/(d-1)
где a,b,d - 1 байт
c,f - 2 байта

Я даже не знаю как подобраться. Учебники не помогают. Там все Хелло, Волд!, а мне математику надо, да так, чтоб пальцем показали.

ZMIY
03.06.2009, 18:37
imul AX,a,2 ;умножаем a на 2 с занесением результата в AX
sub AX,3 ;из AX вычитаем 3, результат остаётся в AX
imul CX, AX,b ;умножаем AX на b с занесением результата в CX
mov BX,d ;запихиваем d в BX
sub BX,1 ;вычитаем из BX (по сути из d) единицу
mov AX,c ;заносим c в AX
idiv BX ;делим содержимое AX(т.е. c) на BX
add AX,CX ;складываем AX и CX, результат остаётся в AX
mov f,AX ;заносим ответ хранящийся в AX в f

PS Я Ассемблером баловался крайний раз лет 15 назад, так что наврать мог безбожно. Поэтому не претендую на истину, эту писанину надо проверять, т.е. это не готовое решение, а скорее набросок.
Чем богаты...

Zorge
03.06.2009, 20:23
ZMIY, и на первой же команде ассемблер ругнется матом - несоответствие типов. А умножение вообще делается над регистрами al, ax и dx:ax (в 32-разрядном режиме добавляются eax и edx:eax).
Хотя конечно да - набросок он и есть набросок. :)
Поэтому:



mov al, [a]
shl al, 1; умножаем a*2 - эквивалентно сдвигу влево на 1 разряд (двоичная СС)
sub al, 3 ; a*2 - 3
mov bl, [b]
imul bl ; (a*2-3)*b
mov cx, ax ; сохраняем результат умножения (a*2-3)*b в cx
mov ax, [c]
mov bl, [d]
dec bl ; d-1
idiv bl ; c / (d-1)
cbw ; изничтожаем остаток от деления в ah - команда расширяет al до ax, сохраняя знак числа
add ax, cx ; (a*2-3)*b + c/(d-1)
mov [f], ax ; сохраняем результат в f


А это уже не набросок - это нормально ассемблируется для любого x86 начиная с i8086.
Синтаксис от Turbo Assembler - пользователям Macro Assembler убрать квадратные скобки вокруг переменных.

orthodox
03.06.2009, 21:26
О! Гран мерси!

ZMIY
03.06.2009, 21:40
А это уже не набросок - это нормально ассемблируется для любого x86 начиная с i8086.

Я знал, что ктонибудь обязательно поправит :ok:

orthodox
10.06.2009, 22:15
Я немножко понаглею.

Лабораторка. Цель - Освоение базово-индексной и базово-индексной со смещением адресаций при работе с 2-мерными массивами, а также форм записи базово-индексной адресаций; изучение способов организации циклов.

Задачка:
Написать программу для суммирования элементов, начиная с нулевого, в шахматном порядке. (NхN, N=4)

Готов сказать спасибо (на тел. копеечку кинуть или еще как).

ZMIY
10.06.2009, 22:45
Задачка:
Написать программу для суммирования элементов, начиная с нулевого, в шахматном порядке. (NхN, N=4)

Не, я второй раз позорится не буду. Нехай Зорге отдувается :D

Zorge
11.06.2009, 17:58
Гм. Ну давайте попробую. Вспомню институт...
Итак:
Так пишут студенты (и простой компилятор языка высокого уровня):


; это запихать в сегмент данных
s dw ?
a dw 4 DUP(?)
dw 4 DUP(?)
dw 4 DUP(?)
dw 4 DUP(?)

; а это в сегмент кода
mov ax,0 ; инициализация суммы
mov cx,0 ; цикл по строкам
for1:
test cx,1 ; проверка на четность строки
jz chet ; если чет, то цикл строки начинаем с 0, иначе с 1
nechet:
mov dx,1
jmp for2
chet:
mov dx,0
for2: ; цикл по столбцам
mov si,cx
shl si,3 ; умножаем на 8 - размер строки массива
mov bx,dx
shl bx,1 ; умножаем на 2 - размер элемента
add ax, [a+si+bx]
inc dx ; пропускаем элемент
cmp dx, 4
jb for2
inc cx
cmp cx,4
jb for1
mov [s],ax ; записываем сумму


А так пишут настоящие "гуру астмы". Суть та же, но нифига не понятно :D


; вставить в сегмент данных
s dw ?
a dw 16 dup(?) ; зачем изображать двумерный массив,
; если в памяти он все равно одномерный?
; вставить в сегмент кода
mov bx,0 ; инициализация суммы
mov si, offset a ; начало массива
cld ; направление перемещения - увеличение (для команды lodsw)
mov cx, 8 ; элементов 16, но т.к. "скачем" через один - то остается 8 циклов
for1:
lodsw ; загрузка в ax слова из адреса ds:si, увеличение si на размер слова
cmp cx, 5 ; проверка на необходимость убирания пропуска
je not4
test cx, 011b ; проверка на необходимость добавления пропуска
jz mor1
inc si
inc si
mor1:
inc si ; пропускаем элемент, для "шахматного" порядка
inc si ; два раза, потому что размер элемента - 2 байта
not4:
loop for1
mov [s],bx ; записываем сумму

orthodox
12.06.2009, 11:09
Да здравствуют советские труженики космоса!

=FPS=Altekerve
12.06.2009, 18:46
Да здравствуют советские труженики космоса!


Диплом-то дадут Zorge, а не тебе. ;)

orthodox
12.06.2009, 19:32
Ну вы как будто никогда не списывали! :D

Alex_K
12.06.2009, 22:16
А полностью уверен, что препод не посещает Сухой.Ру? ;)

Zorge
14.06.2009, 11:30
Диплом-то дадут Zorge, а не тебе. ;)
Спасибо. У меня один уже есть :)
Кстати, на курсовой проект по ассемблеру у меня была задача написать вирус.
И я его написал. Более того - тогдашний AVP 3.0 его пропускал :D
Сейчас не знаю - исходник куда-то потерялся, а исполнимый подсадник вынес то-ли 5-й, то-ли 6-й версии Кашпировский.


Ну вы как будто никогда не списывали! :D
Да списывали, списывали. Я, например, курсовую по САУ делал не сам :)
Теорию я понимаю нормально, а вот с практикой вычислений на калькуляторе у меня труба - то там запятую не там поставлю, то тут минус на плюс перепутаю.
А маткаду не обучен. Вот и... :D


А полностью уверен, что препод не посещает Сухой.Ру? ;)
У нас в институте, например, препод на 100% уверен, что большинство студентов при изготовлении лаб на ассемблере пользуется творчеством предыдущих курсов. Сотрудники компьютерных лабораторий им в этом небесплатно помогают - за полтора десятилетия изучения ассемблера для x86 у них накопилось немало исходных кодов ;)
Как показывает практика, основная засада лабу не написать. Основная засада - её защитить. Особенно если комментариев мало, или они непонятны :)
Лично я в студенческую бытность, "давал списать" второй вариант - и затр... замучиваешься его защищать.
Такой вот я был добрый буратино :D