Просмотр полной версии : Ассемблер. Нужна помощь.
  
orthodox
03.06.2009, 17:25
Надо на асме написать програмку вычисления функции 
f=(a*2-3)*b+c/(d-1)
где a,b,d - 1 байт
c,f - 2 байта
Я даже не знаю как подобраться. Учебники не помогают. Там все Хелло, Волд!, а мне математику надо, да так, чтоб пальцем показали.
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 назад, так что наврать мог безбожно. Поэтому не претендую на истину, эту писанину надо проверять, т.е. это не готовое решение, а скорее набросок. 
Чем богаты...
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
О! Гран мерси!
А это уже не набросок - это нормально ассемблируется для любого x86 начиная с i8086.
Я знал, что ктонибудь обязательно поправит :ok:
orthodox
10.06.2009, 22:15
Я немножко понаглею.
Лабораторка. Цель - Освоение базово-индексной и базово-индексной со смещением адресаций при работе с 2-мерными массивами, а также форм записи базово-индексной адресаций; изучение способов организации циклов.
Задачка:
Написать программу для суммирования элементов, начиная с нулевого, в шахматном порядке. (NхN, N=4)
Готов сказать спасибо (на тел. копеечку кинуть или еще как).
Задачка:
Написать программу для суммирования элементов, начиная с нулевого, в шахматном порядке. (NхN, N=4)
Не, я второй раз позорится не буду. Нехай Зорге отдувается :D
Гм. Ну давайте попробую. Вспомню институт...
Итак:
Так пишут студенты (и простой компилятор языка высокого уровня):
; это запихать в сегмент данных
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
А полностью уверен, что препод не посещает Сухой.Ру? ;)
Диплом-то дадут Zorge, а не тебе. ;)
Спасибо. У меня один уже есть :)
Кстати, на курсовой проект по ассемблеру у меня была задача написать вирус.
И я его написал. Более того - тогдашний AVP 3.0 его пропускал :D
Сейчас не знаю - исходник куда-то потерялся, а исполнимый подсадник вынес то-ли 5-й, то-ли 6-й версии Кашпировский.
Ну вы как будто никогда не списывали! :D
Да списывали, списывали. Я, например, курсовую по САУ делал не сам :)
Теорию я понимаю нормально, а вот с практикой вычислений на калькуляторе у меня труба - то там запятую не там поставлю, то тут минус на плюс перепутаю.
А маткаду не обучен. Вот и... :D
А полностью уверен, что препод не посещает Сухой.Ру? ;)
У нас в институте, например, препод на 100% уверен, что большинство студентов при изготовлении лаб на ассемблере пользуется творчеством предыдущих курсов. Сотрудники компьютерных лабораторий им в этом небесплатно помогают - за полтора десятилетия изучения ассемблера для x86 у них накопилось немало исходных кодов ;)
Как показывает практика, основная засада лабу не написать. Основная засада - её защитить. Особенно если комментариев мало, или они непонятны :)
Лично я в студенческую бытность, "давал списать" второй вариант - и затр... замучиваешься его защищать.
Такой вот я был добрый буратино :D
 
Powered by vBulletin® Version 4.2.5 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot