Более короткая инструкция вызова x86
Для контекста я играю в x86.
00000005 <start>:
5: e8 25 00 00 00 call 2f <cube>
a: 50 push %eax
Несколько звонков позже...
0000002f <cube>:
2f: 89 c8 mov %ecx,%eax
31: f7 e9 imul %ecx
33: f7 e9 imul %ecx
35: c3 ret
call
заняло 5 байтов, хотя смещение укладывается в один байт! Есть ли способ написать call cube
и собрать с GNU ассемблером и получить меньшее смещение? Я понимаю, что можно использовать 16-битные смещения, но в идеале я хотел бы иметь 2-байтовую инструкцию, например call reg
,
1 ответ
Здесь нет call rel8
или любой способ отправить обратный адрес и jmp
менее чем 5 байтов.
Чтобы выйти вперед с call reg
Вам необходимо создать полный адрес в регистре менее чем за 3 байта. Даже REA-относительный LEA не помогает, потому что он существует только в rel32
форма, а не rel8
,
Для одного call
явно не стоит. Если вы можете использовать один и тот же регистр указателя функции для нескольких 2-байтовых call reg
инструкции, то вы выходите вперед даже с всего 2 call
s (5 байт mov reg, imm32
амортизируется в течение 2 call
s стоит 2,5 байта за вызов.) Но это стоит вам зарегистрироваться.
Большинство операционных систем не позволяют отображать что-либо на самых низких страницах (так что ошибки по нулевому указателю разыскиваются), поэтому используемые адреса имеют размер больше 16 бит, вне 16-битного режима.
В 32-битном / 64-битном коде я бы рассмотрел параметры компоновщика, необходимые для отображения вашего кода на нулевой странице, как часть количества байтов в вашем ответе на код-гольф. ( А также /proc/sys/vm/mmap_min_addr
настройка ядра или эквивалент в других ОС)
Вообще избегайте call
в код-гольфе, если можете. Обычно лучше структурировать циклы, чтобы избежать повторного использования кода. например jmp
в середину цикла, чтобы заставить часть цикла запускаться нужное количество раз вместо вызова блока несколько раз.
Я думаю, что я обычно смотрю на вопросы по коду-гольфу, которые естественным образом поддаются машинному коду и могут избежать необходимости одного и того же блока кода из разных мест. Я уже могу часами дорабатывать короткую функцию, поэтому начать ответ на вопрос, который займет больше кода (и, таким образом, будет еще больше места для оптимизации между / по его частям), для меня редко.