2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




На страницу Пред.  1, 2, 3, 4, 5, 6 ... 9  След.

Нужна ли такая тема про ассемблер?
Опрос закончился 24.01.2024, 03:22
Да, почитаю. 50%  50%  [ 12 ]
Да, поспрашиваю. 25%  25%  [ 6 ]
Да, поотвечаю. 4%  4%  [ 1 ]
Мне всё равно, но не против, дерзайте. 17%  17%  [ 4 ]
Нет, не интересно, полно готовой литературы. 0%  0%  [ 0 ]
Нет, ничего в этом не понимаю и не собираюсь. 0%  0%  [ 0 ]
Нет, форум не про это, есть другие более подходящие. 4%  4%  [ 1 ]
Другое ... 0%  0%  [ 0 ]
Всего голосов : 24
 
 Re: Первые и последующие шаги в ассемблере x86/x64
Сообщение16.01.2024, 20:21 
Yadryara в сообщении #1626159 писал(а):
Мне бы конкретику увидеть.
Ну как скажекте. Вот прога для вычисления 45-го числа:
код: [ скачать ] [ спрятать ]
Используется синтаксис ASM
format PE
include 'win32axp.inc'

n=45    ;Какое число Фибоначчи вычислить

.code
main:
;Начало вычислений
        mov     EAX,1           ;x=a1
        mov     EBX,1           ;y=a2
        mov     ECX,2           ;n
cycle:  mov     EDX,EBX
        add     EDX,EAX         ;z=y+x
        mov     EAX,EBX         ;x=y
        mov     EBX,EDX         ;y=z
        add     ECX,1           ;n=n+1
        cmp     ECX,n           ;n-45
        jne     cycle           ;if не равно то уйти к метке
;Конец вычислений, число в EBX
        invoke  wsprintf, buf, fmt1, n, EBX
        invoke  MessageBox, 0, buf, txt1, MB_OK + MB_ICONINFORMATION
        invoke  ExitProcess,0

fmt1:   db      'a(%d)=%d',13,10,0
txt1:   db      'Fibonacci number',0

.data
buf:    rb      1000

.end main
Записываете весь текст в обычный текстовый файл с расширением .asm, компилируете через FASM, получается файл .exe размером 1536 байт, запускаете его, получаете окошко с числом 1134903170.

Первые две строки это инструкция компилятору сделать exe формата x86 и включить в текст программы и файл win32axp.inc из поставки FASM с объявлением функций WinAPI.
Команды с точкой в начале это инструкции компилятору.
Команда db это инструкция компилятору выделить память и положить в неё следующую строку.
Команда rb это инструкция компилятору выделить память и ничего туда не класть (но винда сама там всё обнулит).
Команды invoke это вызов функций WinAPI, к ассемблеру практически не относится. Это "магия" для показа числа в окошке винды.
Команда mov копирует правое в левое.
Команда add прибавляет к левому правое (и выставляет флаги, но тут они не нужны).
Команда cmp вычитает правое из левого и выставляет флаги по результату (ни левое ни правое не меняется). В частности флаги нуля (если левое равно правому) и переноса (если левое меньше правого).
Команда jne (и синоним jnz) передает управление на указанную метку если флаг нуля не установлен.
EAX, EBX, ECX, EDX - регистры (переменные внутри процессора). Ещё можно использовать ESI, EDI, EBP.
Задание "на дом": преобразовать формулу a3=a2+a1 в формулу a4=a3+a2+a1 (первые три как обычно по 1) и вычислить скажем 30-е число (20603361).
Задание "со звёздочкой": вычислить 50-е число и подумать почему оно неправильное.
Числа Фибоначчи для проверки есть например здесь: https://oeis.org/A000045/b000045.txt

PS. Без информации об устройстве проца внутри у меня ощущение что начал с середины ...
PPS. Админы запретили прикладывать .asm файлы, так что всё сами, ручками.

 
 
 
 Re: Первые и последующие шаги в ассемблере x86/x64
Сообщение16.01.2024, 20:38 
Аватара пользователя
Dmitriy40 в сообщении #1626084 писал(а):
...ещё хороших книг (только на русском) и по ассемблеру... и по оптимизации.
Генри Уоррен: Алгоритмические трюки для программистов
Много работы с битами. Прекрасная книга. У меня она (бумажная) лет 20. Читал не раз, и частями пересматривал.

-- 16.01.2024, 20:51 --

Называть ассемблер компилятором всё же странно, т.к. это именно ассемблер.
https://ru.m.wikipedia.org/wiki/%D0%90% ... 0%B5%D1%80
https://ru.m.wikipedia.org/wiki/%D0%A2% ... 0%BE%D1%80

-- 16.01.2024, 20:57 --

В Википедии про ассемблер написано "Трансляцию ассемблерных программ иногда также называют компиляцией.", но это крайне-крайне иногда (*) и уж точно не в курсе для начинающих.

(*) Не припомню такого называния за всё то время (почти 40 лет), что связан с программированием.

 
 
 
 Re: Первые и последующие шаги в ассемблере x86/x64
Сообщение16.01.2024, 21:02 
Не хочу грузить различиями между компилятором, транслятором, ассемблером (и языком ассемблера и технической сборочной машиной), компоновщиком, линковщиком, библиотекарем, и ещё тучей вспомогательных утилит. Всё что преобразует один файл (в частности текстовый) в другой (в частности исполняемый) - компилятор. А то щас вспомню что .exe вовсе не машинный код. Или что ассемблер может выдавать и .hex файл (кажется не FASM, но для любого МК может, а иногда и только его!), который уже совсем не машинный код, а текст.
К тому ровно по Вашей второй ссылке: "Компилятор — это вид транслятора, преобразующий исходный код с какого-либо языка программирования на машинный язык[6]" и "Ассемблер — компилятор, преобразующий текст с языка ассемблера на машинный язык.". Так что и ассемблер (как программа) тоже компилятор.
Так что я не улавливаю принципиальной разницы между .c и .asm файлами. И то и другое текст. И в результате компиляции из обоих появляется .exe.

-- 16.01.2024, 21:12 --

Впрочем, если в список пунктов добавится деление проекта на несколько независимых исходников и компиляция их по отдельности и потом связывание в один исполняемый файл - ОК, вот тогда и расскажу про отличия и детали процесса. Или отошлю к умным книжкам. Пока не планировал.

 
 
 
 Re: Первые и последующие шаги в ассемблере x86/x64
Сообщение16.01.2024, 22:02 
Аватара пользователя
Фасм нашёл, как компилить не помню. Исправил так:

код: [ скачать ] [ спрятать ]
Используется синтаксис ASM
format PE
include 'win32axp.inc'

n=30    ;Какое число Трибоначчи вычислить

.code
main:
;Начало вычислений
        mov     EAX,1           ;x=a1
        mov     EBX,1           ;y=a2
        mov     EBP,1           ;t=a3
        mov     ECX,3           ;n
cycle:  mov     EDX,EBP
        add     EDX,EAX         ;z=t+x
        add     EDX,EBX         ;z=t+x+y
        mov     EAX,EBX         ;x=y
        mov     EBX,EBP         ;y=t
        mov     EBP,EDX         ;t=z
        add     ECX,1           ;n=n+1
        cmp     ECX,n           ;n-30
        jne     cycle           ;if не равно то уйти к метке
;Конец вычислений, число в EBP
        invoke  wsprintf, buf, fmt1, n, EBP
        invoke  MessageBox, 0, buf, txt1, MB_OK + MB_ICONINFORMATION
        invoke  ExitProcess,0

fmt1:   db      'a(%d)=%d',13,10,0
txt1:   db      'Tribonacci number',0

.data
buf:    rb      1000

.end main


Dmitriy40 в сообщении #1626177 писал(а):
Задание "со звёздочкой": вычислить 50-е число и подумать почему оно неправильное.

Видимо переполнение где-то.

 
 
 
 Re: Первые и последующие шаги в ассемблере x86/x64
Сообщение16.01.2024, 22:45 
Yadryara в сообщении #1626198 писал(а):
Фасм нашёл, как компилить не помню.

0. Распаковываете в папку (я распаковал на диске F).
1. Копируете файл пример из сообщения на форуме в файл (пусть fib.asm) в корень директории fasm.
2. Если пути не настроены, то указываем в файле относительный путь к включаемому файлу, т.е.
заменяем
include 'win32axp.inc'
на
include 'INCLUDE\win32axp.inc'.
выполняем в командной строке
fasm.exe fib.asm

Появляется исполняемый файл fib.exe
Запускаем это оконное приложение. Оно открывает окно с результатом
a(45) = 1134903170

(Можно запустить и оконный компилятор fasmw.exe. Но такой простой пример проще консольным.)

 
 
 
 Re: Первые и последующие шаги в ассемблере x86/x64
Сообщение16.01.2024, 23:08 
Yadryara в сообщении #1626198 писал(а):
Фасм нашёл, как компилить не помню.
Сделать .cmd файл (например f.cmd) с содержимым:
@set INCLUDE=C:\Program Files (x86)\FASM\INCLUDE
@"C:\Program Files (x86)\FASM\fasm" %*

Конечно если FASM в этой папке. Иначе указать правильную.
И запускать компиляцию файла prog1.asm командой в консоли f.cmd prog1.asm. Или мышкой перетащить prog1.asm на иконку f.cmd.
Я предпочитаю именно такой способ, с отдельным cmd файлом, чтобы не указывать в каждой программе где сегодня лежат файлы FASM-а (как правильно написал GAA), достаточно указать лишь в cmd и всё.

Оба задания верно.
Переполнение - число не влезает в регистр и команда add (какая-то) оставляет от правильного числа лишь 32 младших бита. И снова. И снова. Потому что, как будет написано во введении, процессор делает лишь ровно то что ему конкретно указано и на йоту больше. Сказано сложить - сложит. А про проверку переполнения ничего не сказано. И если компиляторы нормальных языков (и обычно не С) или сами добавят проверку или ругнутся предупреждением (мол что-то тут может быть не так) или добавят код показа ошибки если она возникнет, то на асме всё надо писать самому, чётко и конкретно.
В данном случае контроль за переполнением можно сделать например так: после каждой команды add добавляем команду jc ovf (если установлен флаг переноса (переполнения при сложении), то перейти к метке ovf), а после последней invoke (или после двух текстовых строк, но до .data) добавляем три строки:
Используется синтаксис ASM
ovf:    invoke  MessageBox, 0, err1, txt1, MB_OK + MB_ICONSTOP
        invoke  ExitProcess,199
err1:   db      'Overflow!',13,10,0
Тут сплошная магия: дёргаем WinAPI показать окно с заданным текстом и заголовком и иконкой крестика и кнопкой, а потом завершаем программу с другим кодом завершения (1-255).

 
 
 
 Re: Первые и последующие шаги в ассемблере x86/x64
Сообщение17.01.2024, 02:29 
SergeCpp в сообщении #1625917 писал(а):
Посоветую книгу The Art of Assembly Language известного автора Randall Hyde, названную по аналогии с трудом Д. Кнута. https://en.wikipedia.org/wiki/Randall_Hyde
Спасибо за совет. Но я в нее заглянул, и для меня там совершенно китайская грамота. По-видимому, лично для меня будет лучше всего внимательно перечитать книжку Шнайдера, вышеупомянутую (которой, странно, нет в либгене, но была найдена в твирпксе). Там уж для полных дятлов, вроде меня, разжёвано.

 
 
 
 Re: Первые и последующие шаги в ассемблере x86/x64
Сообщение17.01.2024, 02:54 
Аватара пользователя
GAA
Dmitriy40

Спасибо. С компиляцией вроде разобрался. Сделал двумя способами. Оба числа, и Фибоначчи $a(45) = 1134903170$ , и Трибоначчи $a(30) = 20603361$ совпали.

Dmitriy40 в сообщении #1626214 писал(а):
процессор делает лишь ровно то что ему конкретно указано и на йоту больше.

Пропущено "ни" ? И ни на йоту больше ?

Dmitriy40 в сообщении #1626119 писал(а):
переписать программу для вычисления любого числа Фибоначчи по формуле Бине

А есть ли для Трибоначчи аналогичная формула :-) :wink:

 
 
 
 Re: Первые и последующие шаги в ассемблере x86/x64
Сообщение17.01.2024, 05:00 
Dmitriy40 в сообщении #1626177 писал(а):
Задание "со звёздочкой": вычислить 50-е число и подумать почему оно неправильное.
У меня 50 и 55 значения сходятся с данными по указанной Вами выше ссылке.
код: [ скачать ] [ спрятать ]
Используется синтаксис ASM
format PE64
include 'win64axp.inc'

n=55    

.code
main:
        mov     RAX, 1           ;x=a1
        mov     RBX, 1           ;y=a2
        mov     ECX, 2           ;n
cycle:  
        mov     RDX, RBX
        add      RDX, RAX       ;z=y+x
        mov     RAX, RBX        ;x=y
        mov     RBX, RDX        ;y=z
        add      ECX, 1            ;n=n+1
        cmp     ECX, n            ;n-45
        jne     cycle                ;

        invoke  wsprintf, buf, fmt1, n, RBX
        invoke  MessageBox, 0, buf, txt1, MB_OK + MB_ICONINFORMATION
        invoke  ExitProcess,0

fmt1:   db      'a(%u)=%I64u',13,10,0
txt1:   db      'Fibonacci number',0

.data
buf:    rb      1000

.end main


-- Wed 17.01.2024 04:23:12 --

В примере Dmitriy40 небольшая опечатка типа данных при преобразовании числа в строку. Нужно не d, а u.
Иначе переполнение может ещё не произойти, но программа выведет отрицательное число:
a(47) = -1323752223.
Тогда как с u:
a(47) = 2971215073

 
 
 
 Re: Первые и последующие шаги в ассемблере x86/x64
Сообщение17.01.2024, 08:13 
Аватара пользователя
GAA, Ваша прога у меня не работает. Вы небось для 64х сделали.

GAA в сообщении #1626244 писал(а):
В примере Dmitriy40
небольшая опечатка типа данных при преобразовании числа в строку.

Может это специально сделано. С назидательной целью.

 
 
 
 Re: Первые и последующие шаги в ассемблере x86/x64
Сообщение17.01.2024, 10:18 
Yadryara в сообщении #1626260 писал(а):
Вы небось для 64х сделали.
Да. В первой строке (format PE64) указано --- для x64.
Вот два варианта для win32. Привожу только вычислительную часть. Вывод результата читатель напишет по своему вкусу.
Проверок переполнения нет. Оптимизации нет.
(Под win32 результат функция возвращает в вершине стека FPU, но для наглядности выполнено сохранение в переменную result.)
FPU:
Используется синтаксис ASM
   fld1
   fld1
   mov  ecx,  2
 cycle:
   fxch st(1)
   fadd st(0), st(1)
   add  ecx,  1
   cmp  ecx,  n
   jne  cycle
   fistp result


SSE:
one --- переменная в которой хранится 1. result --- переменная с результатом. (Под x64 результат функция возвращает в xmm0, но под x32 зависит от соглашений компилятора. Если компилятор поддерживает соглашение, что возвращает через xmm0, то сохранение в память избыточно.)
код: [ скачать ] [ спрятать ]
Используется синтаксис ASM
   movq xmm0, one
   movq xmm1, one
   mov  ecx,  2
 cycle:
   paddq xmm0, xmm1
   add  ecx,  1
   cmp  ecx,  n
   je   res
   paddq xmm1, xmm0
   add  ecx,  1
   cmp  ecx,  n
   jne  cycle
   movq xmm0, xmm1
res:
   movq result, xmm0


-- Wed 17.01.2024 09:20:27 --

Yadryara в сообщении #1626260 писал(а):
Может это специально сделано. С назидательной целью.
Конечно! Вот мы увидели и отметили. (Реакция читателей.)

-- Wed 17.01.2024 09:27:50 --

Да, два приведенных варианта --- это юмор. По смыслу нужно делать длинную арифметику. Видимо об этом Dmitriy40 и расскажет.

 
 
 
 Re: Первые и последующие шаги в ассемблере x86/x64
Сообщение17.01.2024, 11:02 
Аватара пользователя
Yadryara в сообщении #1626241 писал(а):
А есть ли для Трибоначчи аналогичная формула :-) :wink:

Есть.
В Википедии в статье "Числа трибоначчи" она приведена, там даже есть довольно простая формула, не требующая комплексных чисел (никакие процессоры, про которые я знаю, не умеют работать с комплексными числами напрямую).

 
 
 
 Re: Первые и последующие шаги в ассемблере x86/x64
Сообщение17.01.2024, 13:19 
Аватара пользователя
worm2 в сообщении #1626269 писал(а):
В Википедии в статье "Числа трибоначчи" она приведена, там даже есть довольно простая формула,

То-то и оно, что есть формула проще, но она в Вики так и не приведена...

 
 
 
 Re: Первые и последующие шаги в ассемблере x86/x64
Сообщение17.01.2024, 15:24 
Yadryara в сообщении #1626260 писал(а):
GAA в сообщении #1626244 писал(а):
В примере Dmitriy40 небольшая опечатка типа данных при преобразовании числа в строку.
Может это специально сделано. С назидательной целью.
Нет, это моя недоработка. Привык к PARI, где числа длинные и %d работает правильно. Хотя сам везде в асм пишу %u, но вот тут не обратил внимания, сфокусировался на вычислительной части, а это объяснять и не собирался.

GAA
Про x64 я планировал рассказать позже, там предел 93-е число Фибоначчи, как раз для увеличения диапазона. И не у всех есть x64 ОС.
А уж про FPUI и SSE ещё позже, там много дополнительных моментов надо оговорить.

GAA в сообщении #1626265 писал(а):
Да, два приведенных варианта --- это юмор. По смыслу нужно делать длинную арифметику. Видимо об этом Dmitriy40 и расскажет.
Вовсе нет, это прекрасные примеры как одно и то же сделать разными методами. Я примерно так и хотел сделать, только для интереса по формуле Бине чтобы аргументировать расширением диапазона n.
Про длинную арифметику я собирался рассказать коротко, только про сложение/вычитание, умножение на малое число (в регистре) и деление на малое число (это всё практически полезно). Остальное оставить за скобками. В контексте высокоскоростных вычислений всё прочее слишком медленно и требует изменения алгоритма для своего исключения. :mrgreen:

Yadryara в сообщении #1626241 писал(а):
Пропущено "ни" ? И ни на йоту больше ?
Да, опечатка.
Yadryara в сообщении #1626241 писал(а):
А есть ли для Трибоначчи аналогичная формула :-) :wink:
Понятия не имею, это не асм, а математика. Думаю и в вики и в OEIS A000213/A000073 по ссылкам есть (в вики точно вижу, T(n)=...).
По приведённой выше ссылке формула тоже есть, tn=...

-- 17.01.2024, 15:31 --

Yadryara в сообщении #1625921 писал(а):
А спрашивать уже можно или погодить пока?
Так что у Вас за вопрос то был? А то что-то всё в кучу начали мешать, и SSE с FPU, и соглашения о передаче параметров, и процедуры/функции, и переменные в памяти, и x64 с x86, и математику с асмом ... Тогда уж проще так и продолжать, чисто ответы на вопросы, без лекций. И не надо будет второй темы, по всем техническим вопросам можно в книги/вики отсылать где всё описано подробнее чем могу я (правда не факт что короче и понятнее).

-- 17.01.2024, 15:52 --

GAA в сообщении #1625922 писал(а):
Да, поспрашиваю.
Раз тему оставили здесь, то уже вполне пора. Только учтите что я не преподаю нигде, чистый практик (и самоучка, так что и в теории весьма плаваю).

 
 
 
 Re: Первые и последующие шаги в ассемблере x86/x64
Сообщение17.01.2024, 16:04 
Аватара пользователя
Yadryara в сообщении #1626288 писал(а):
То-то и оно, что есть формула проще, но она в Вики так и не приведена...

Да вот же она: $t_n = \left\lfloor\dfrac{3bC^n}{b^2-2b+4} \right\rceil,$ где $C=\dfrac{1+\sqrt[3]{19+3\sqrt{33}}+\sqrt[3]{19-3\sqrt{33}}}{3}$, $b = \sqrt[3]{586 + 102 \sqrt{33}}$, а $\lfloor \cdot \rceil$ — округление до ближайшего целого.
$C$ и $\dfrac{3b}{b^2-2b+4}$ можно заранее вычислить, это константы. Осталось только $C$ возвести в степень.

 
 
 [ Сообщений: 133 ]  На страницу Пред.  1, 2, 3, 4, 5, 6 ... 9  След.


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group