- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
#include <stdio.h>
int main()
{
printf("test\n");
__asm volatile (".rept 10\n");
printf("test\n");
__asm volatile (".endr");
return 0;
}
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
+140
#include <stdio.h>
int main()
{
printf("test\n");
__asm volatile (".rept 10\n");
printf("test\n");
__asm volatile (".endr");
return 0;
}
Еще немного поиздевался над GCC. Через ассемблерные вставки, точнее через вставку директивы .rept иногда можно повторить некоторый кусок кода несколько раз. Работает это далеко не всегда
http://sourceware.org/binutils/docs/as/Rept.html
Этот .rept по сути просто копипастит кусок кода
foo(1);
__asm volatile (".endr");
превратится в законное:
push 1
call foo
push 1
call foo
или в распидарасиваемое:
push 1
call foo
call foo
при условии что функция foo stdcall конечно
Кроме того, просматривая ассемблерные выхлопы GCC я в свое время обнаружил то, что он неоптимальным образом записывает в стек даннные, если они объявлены таким вот образом
По поводу этого я даже в мейл лист GCC писал, http://gcc.1065356.n5.nabble.com/Ways-to-fill-the-stack-td912561.html
Ну в первом случае да, херня какая-то получилась с шестью movb. А во втором - все норм, т.к. пара mov'ов эффективней, чем пара push'ей.
As you can see, mov %r8,(%rsp) produse 4 bytes: 4c 89 04 24 and mov %rdi,0x8(%rsp) produces 5 bytes: 48 89 7c 24 08 push %r8 produces only 2 byte 41 50 and push %rax (or %rcx %rdx ...) produces one byte You can check other instruction length, for example movq %rax, (%rsp) etc.
А нет особого смысла слишком уменьшать длину опкодов. Декодер в проце, емнип, захлебывается на 6 командах на 16 байт. Так что уменьшение длины кода, имхо, имеет смысл разве что на оптимизации под минимальный размер (контроллеры и т.п.), но никак не на скорость (которая и происходит на -O2/-O3).