LINUX.ORG.RU

Ассемблер в Linux для программистов C

 , ,


0

0

Дмитрий Грибенко опубликовал замечательную книгу по синтаксису AT&T.

Эта книга — для людей, которые уже хотя бы немного разбираются в том, как работает железо. Многое ещё не написано (например, машинная арифметика — чистая теория, операции с числами с плавающей запятой на x86 и многое другое). Низкоуровневая работа с железом не освещена вообще, так как ставка сделана на user-mode, а не на kernel-mode.

Для чтения этой книги никаких знаний о Linux не требуется (кроме, разумеется, «как создать текстовый файл» и «как запустить программу в консоли»).

>>> Книга

★★

Проверено: UVV ()
Ответ на: комментарий от qewerty

>Т.е. тут код под венду

Под венду на асме не пишут, там уж это точно не Ъ. Скорее это код под бздю.

anonymous
()
Ответ на: комментарий от qewerty

Да мне просто интересно стало - 100% можно написать на asm так что будет работать быстрей чем на С :) Даже с оптимизацией -O4 - достаточно просто убрать ненужные команды работы со стеком. Люди никак не могут понять что писать на asm и знать его - не одно и тоже, если первое под linux практически бессмысленно (кроме случаев оптимизации отдельных частей кода) то второе для эфективной работы необходимо.

koTuk
()
Ответ на: комментарий от anonymous

>Итого C в 3 раза быстрее (гыгыгы).

Что ты ржешь как конь ретивый?

Классический пример пузырьковой сортировки, из книги Зубкова С.В. "Ассемблер для DOS, Windows и Unix" (переписанный мной под 32-битные инструкции):

; Процедура bubble_sort
; сортирует массив двойных слов методом пузырьковой сортировки
; ввод: DS:EDI = адрес массива
;       EDX = размер массива (в двойных словах)
bubble_sort        proc    near
        pushadw
        cld
        cmp        edx,1
        jbe        sort_exit        ; выйти, если сортировать нечего
        dec        edx
sb_loop1:
        mov        ecx,edx          ; установить длину цикла
        xor        ebx,ebx          ; EBX будет флагом обмена
        mov        esi,edi          ; ESI будет указателем на
                                    ; текущий элемент
sn_loop2:
        lodsdw                      ; прочитать следующее слово
        cmp        eax,dword ptr [esi]
        jbe        no_swap          ; если элементы не
                                    ; в порядке,
        xchg       eax,dword ptr [esi] ; поменять их местами
        mov        dword ptr [esi-4],eax
        inc        ebx              ; и установить флаг в 1,
no_swap:
        loop       sn_loop2
        cmp        ebx,0            ; если сортировка не закончилась,
        jne        sn_loop1         ; перейти к следующему элементу
sort_exit:
        popadw
        ret
bubble_sort        endp


В принципе процедуру еще есть куда оптимизировать... Мне впадлу. И так сойдет.

Давай, напиши на сях процедуру работающею быстрее. Естественно сортируемый массив должен быть одинаков.

anonymous
()
Ответ на: комментарий от anonymous

> Это какой архитектуры опкоды?

Да. Гоню. Без w в конце, естественно :) Просто написал по памяти... А память подвела, так-как учил asm лет 15 тому...

anonymous
()
Ответ на: комментарий от scaldov

Тут наверно имелась ввиду архитектура :) А то какое-то сравненине ни о чем.

koTuk
()
Ответ на: комментарий от scaldov

>ассемблер под x86 говно. >x86_64 ещё куда ни шло.

Те же яйца, только в профиль.

anonymous
()
Ответ на: комментарий от scaldov

> а рулят ассемблеры ARM

ага
с 8-битной арифметикой

kto_tama ★★★★★
()

Обновленный тест.

Сорец: http://pastie.org/215505

То что получилось: http://pastie.org/215506

~/test/great_shout_out$ ./great_shoutout

asm: 0.002810

c: 0.003134

~/test/great_shout_out$ ./great_shoutout

asm: 0.002922

c: 0.003035

~/test/great_shout_out$ ./great_shoutout

asm: 0.002847

c: 0.002781

~/test/great_shout_out$ ./great_shoutout

asm: 0.002924

c: 0.002902

На большом количестве данных cmov не дает выйгрыша.

anonymous
()
Ответ на: комментарий от anonymous

> Мне кажется, тут неплохой выигрыш даст repne scas.

Ой, конечно же repne cmpl

anonymous
()

Нет слов, Только чувства благодарности

srgaz
()
Ответ на: комментарий от anonymous

Сорец: http://pastie.org/215533

То что получилось: http://pastie.org/215535

~/test/great_shout_out$ ./great_shoutout_bb

asm: 0.013173

c: 0.007904

~/test/great_shout_out$ ./great_shoutout_bb

asm: 0.012490

c: 0.008302

Сомнительный момент с loop'ом, что-то он не туда позиционируется. пришлось 3 nop'а вставить чтобы в нужное место попадал. Похоже баг компилятора.

anonymous
()

64х битное http://pastie.org/215548

http://pastie.org/215549

asm: 0.012027 c: 0.005227

asm: 0.012778 c: 0.006518

Хе, похоже правду говорят, что 64х битный режим быстрее за счет большего количества регистров.

C: boxtest

anonymous
()

ух ты , как раз экзамен по асм. через 2 недели!

anonymous
()
Ответ на: комментарий от anonymous

>Сколько было уже новостей по этой теме, а внятно объяснить, чем же плох синтаксис TASM, так никто и не объяснил.

он неоднозначен. И требует "исключений" всяких. Режим IDEAL получше, но только костыль.

dikiy ★★☆☆☆
()
Ответ на: комментарий от anonymous

loop неэффективен
попробуй так в старом тесте на нахождение максимального элемента

bash-3.2# cat test_asm.s 
.data
.globl _array
.globl _array_end

.text
.globl _asm_find
_asm_find:
        pushl %ebx
        pushl %ecx

        movl  $_array_end, %ecx
        movl  (%ecx), %ecx
        movl  $_array, %ebx
        movl  (%ebx), %ebx

        subl  %ebx, %ecx
        shr   $2, %ecx
        movl  $0, %eax
loop_start:               
        cmpl  %eax, (%ebx)
        jbe   less        
        movl  (%ebx), %eax
less:
        addl  $4, %ebx    
        decl  %ecx
        jnz   loop_start

        popl %ecx
        popl %ebx
        ret

koTuk
()
Ответ на: комментарий от koTuk

Угу…

но, имхо, знание о том эффективен ли loop или нет надо оставлять компилятору.

anonymous
()

Челу мегареспект и спасибище

anonymous
()
Ответ на: комментарий от anonymous

>Традиционный синтаксис TASM получше конечно, но удобнее всего писать на асме под макро-ассемблер любой всеми компании:) Там удобство написания и читаемость кода практически приближается к языку Си. Макроподстановки, invoke'и. Никому бы не было плохо, если бы нечто похожее появилось и под линукс, естественно не под флагом микрософт)

Всё это было и в TASM, плюс более вменяемый и однозначный синтаксис. По умолчанию он работал в режиме MASM, кстати.

madcore ★★★★★
()
Ответ на: комментарий от anonymous

>Давай, напиши на сях процедуру работающею быстрее. Естественно сортируемый массив должен быть одинаков.

абсолютно тупой сишный код
void bubble_sort(int *arr, int count) {
        int i, j;
        do {
                j=0;
                for (i=1; i<count; ++i) {
                        if (arr[i-1]<arr[i]) {
                                int t=arr[i-1];
                                arr[i-1]=arr[i];
                                arr[i]=t;
                                j++;
                        }
                }
        } while (j);
}

gcc 3.4.5 из mingw превратил в произведение искуства:
_bubble_sort:
        pushl   %edi
        pushl   %esi
        pushl   %ebx
        movl    16(%esp), %ebx
        movl    20(%esp), %edi
        .p2align 4,,15
L2:
        movl    $1, %eax
        xorl    %esi, %esi
        cmpl    %edi, %eax
        jge     L11
        .p2align 4,,15
L18:
        movl    -4(%ebx,%eax,4), %ecx
        movl    (%ebx,%eax,4), %edx
        cmpl    %edx, %ecx
        jge     L7
        movl    %edx, -4(%ebx,%eax,4)
        incl    %esi
        movl    %ecx, (%ebx,%eax,4)
L7:
        incl    %eax
        cmpl    %edi, %eax
        jl      L18
L11:
        testl   %esi, %esi
        jne     L2
        popl    %ebx
        popl    %esi
        popl    %edi
        ret

А ваш 16-битный фрагмент нечем собрать, чтобы потестить :(
Если считать по тактам, учитывая конвеер, то ваш код сосёт.

anonymous
()
Ответ на: комментарий от Quasar

> бывают очень полезны

Ню-ню! Вреда от них больше, чем пользы.

.data
.cstring
.align 2
strhello:
.asciz "Hello, Darwin!\n"
len = . - strhello
.text
.align 2
.globl _start
_start:
li r0,4
li r3,1
lis r4,ha16(strhello)
ori r4,r4,lo16(strhello)
li r5,len
sc
li r0,1
li r3,0
sc

Ну а теперь

1) скажите для какого проца ЭТО я использовал?

2) как это перенести под Intel-архитектуру?

LOL! :)

Знание ассемблера нужно тем, кто gcc пишет. Остальным - только вредит.

Bioreactor ★★★★★
()
Ответ на: комментарий от anonymous

>>Синтаксис AT&T ужасен..

Не более чем интелевый. Во первых пространство имен регистров наглухо отделено от пространсва имен переменных, и от пространства имен команд за счет префиксов, что дает гарантию совместимости старых программ с новыми процессорами. Во вторых ИМХО проще юзать префикс команды нежели писать достаточно длинные преобразования. В третьих AT&T охватывает все команды процессора, тогда как в интелевом синтаксисе часть команд интерпретации не имеет и пробивается ручками в машинных кодах. В четвертых стандартный as понимает оба синтаксиса, а в сети полно конверторов из синтаксиса интел в ат и наоборот.

Плюс ко всему макросы не являются изобретением M$, соответсвенно аппарат макросов со схожим функционалом существует практически во всех ассемблерах. Читабельность кода не является заслугой того или иного ассемблера/ЯП, ибо относится к культуре программирования.

anonymous
()
Ответ на: комментарий от Bioreactor

>>Знание ассемблера нужно тем, кто gcc пишет. Остальным - только вредит.

Знание асма нужно для хакинга закрытого кода, к примеру. Для написания n разрядной арифметики под p разрядный процессор, где n>p. На асме опять жеж прописывают процедуры сравнения и сортировки. В общем есть куча областей где любой немашинный изыкк сливает по полной.

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

anonymous
()
Ответ на: комментарий от anonymous

> Оставьте асм компилятору и тем кто знает что делает! Нельзя сеять дезу в умы людей, что написанное на асме более чем в 9000 раз быстрее написанного на других языках! Ну почему же? :) Вне всякого сомнения: в среднем, 100 строк исходной программы на asm, выполнятся в 9000 раз быстрее, чем 100 строк исходной программы на Джаве или даже C++. :)

anonymous
()
Ответ на: комментарий от anonymous

>Во первых пространство имен регистров наглухо отделено от пространсва имен переменных, и от пространства имен команд за счет префиксов, что дает гарантию совместимости старых программ с новыми процессорами.

Как правило ассемблерные программы все равно переписываются под новые процессоры, а префикс регистра на спарках приводит например к такому извращению: fmuld %%f0, %%f2, %%f1 У них и так каждый регистр имеет префикс %, плюс нужно добавлять еще один % для асма.

>Во вторых ИМХО проще юзать префикс команды нежели писать достаточно длинные преобразования.

Маразм: movl %eax, %ebx Ежу понятно, что указание длин переменных здесь лишнее, но без него никак. В FASM например указание размерности можно делать как приведение типа в C.

>В третьих AT&T охватывает все команды процессора, тогда как в интелевом синтаксисе часть команд интерпретации не имеет и пробивается ручками в машинных кодах.

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

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

anonymous
()
Ответ на: комментарий от anonymous

>Знание асма нужно для хакинга закрытого кода, к примеру.

Закрытый код не нужен, вирусные аналитики тоже, ибо бесполезны для линакса.

>Для написания n разрядной арифметики под p разрядный процессор, где n>p.

Что в этом такого творческого, с чем не справится машина? В нормальных языках есть bignum-ы с неограниченной разрядностью, для убогеньких недоязычков библиотека gmp.

>На асме опять жеж прописывают процедуры сравнения и сортировки.

Пишут, но результат выполняется медленнее чем сгенерированный компилятором.

>В нормалных прогах на асме процессор не надо угадывать, он директивой выбираеццо.

LOL! Директивой можно выбрать один из вариантов программ. А для этого нужно их нужно кропотливо написать под каждый процессор в отдельности.

>Ежели мозг далек от железа - неh делать в айти.

Если моск близок к железу то это Компьютер Головного Мозга, терминальная стадия.

anonymous
()
Ответ на: комментарий от KUser

>>Но где без асма никуда - написание самомодифицирующегося кода :)

>А Lisp? :)

Скомпилированный Lisp уже никого не смодифицирует...

anonymous
()
Ответ на: комментарий от anonymous

> Скомпилированный Lisp уже никого не смодифицирует...

Бредишь? Какая разница, скомпилированный или нет? Скомпилирует модифицированное выражение заново.

anonymous
()
Ответ на: комментарий от anonymous

Типа как в JIT? Но зачем вообще компилировать Лисп в x86, фишка которого работа с кодом как с данными, и потому меняющийся код?

KUser
()
Ответ на: комментарий от anonymous

>Ежели мозг далек от железа - неh делать в айти.

Такие люди как, Hindley J.R., Seldin J.P. , H.B. Curry никогда не видели микропроцессора.

Sun-ch
()
Ответ на: комментарий от anonymous

>Но где без асма никуда - написание самомодифицирующегося кода :)

Бггг, особенно если приложение не может писать в область кода.

madcore ★★★★★
()
Ответ на: комментарий от KUser

> Типа как в JIT? Но зачем вообще компилировать Лисп в x86, фишка которого работа с кодом как с данными, и потому меняющийся код?

Тоже бредишь?

Какая тебе разница, в каком виде этот код исполняется? Когда он готов для исполнения, тебе с ним как с данными уже работать не придётся.

anonymous
()

Вчера читал четыре часа подряд. Написано хорошо, легко, ясно. Сначала правда было некое непонимание. Как это от С к Ассемблеру? Но потом по мере чтения это быстро прошло. Ведь многие конструкции, которые в Ассемблере просто естественны в С преподаются как нечто продвинутое ( указатели к примеру). Мне кажется это крайн противоественным - учить сначала присвоение абстрактной переменной данных, а потом узнать как адресуются данные в машине. Но судя даже по чтению этого треда, полно умников которые считают что это не важно. Видимо такие вот умники и додумались объвить ООП парадигмой чуть ли платоновского типа. Железо, ассемблер - это слова настоящего мужчины. Еще раз респект автору.

anonymous
()
Ответ на: комментарий от anonymous

Ну если я например сделаю функцию, которая превращает в код зашифрованные данные, то наверно и после компиляции придётся работать с ним как с данными, а полученный код как-то компилировать, или исполнять как есть. Врядли на Lisp нельзя написать такого.

KUser
()
Ответ на: комментарий от anonymous

В то время как все прогрессивное человечество стремится к виртуализации и глобализации, находятся чудаки, изучающие реликтовые языки и архитектуры.

Sun-ch
()
Ответ на: комментарий от Sun-ch

> В то время как все прогрессивное человечество стремится к виртуализации и глобализации, находятся чудаки, изучающие реликтовые языки и архитектуры.

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

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.