Neden GCC pad NOPs ile fonksiyonları mu?
Kısa bir süre için C ile çalışıyoruz ve çok yakın zamanda MİGROS girmeye başladım. Ben bir program derleme:
int main(void)
{
int a = 0;
a = 1;
return 0;
}
Bu objdump demontaj kodu vardır, ama ret sonra nops:
...
08048394 <main>:
8048394: 55 push ëp
8048395: 89 e5 mov %esp,ëp
8048397: 83 ec 10 sub $0x10,%esp
804839a: c7 45 fc 00 00 00 00 movl $0x0,-0x4(ëp)
80483a1: 83 45 fc 01 addl $0x1,-0x4(ëp)
80483a5: b8 00 00 00 00 mov $0x0,êx
80483aa: c9 leave
80483ab: c3 ret
80483ac: 90 nop
80483ad: 90 nop
80483ae: 90 nop
80483af: 90 nop
...
Nops hiçbir şey öğrendim, ve o zamandan beri ret sonra bile idam olmaz.
Benim soru: neden? ELF(linux-86) ile çalışmayacağını söyledi .metin bölümü( ana) herhangi bir boyut?
Herhangi bir yardım, sadece öğrenmeye çalışıyorum memnun olurum.
CEVAP
Öncelikle gcc
her zaman böyle yapmaz. Doldurma otomatik olarak -O2
-O3
açık olan -falign-functions
tarafından kontrol edilir:
-falign-functions
-falign-functions=n
Align sonraki işlevleri başlangıç güç-of-iki
n
,n
byte atlanıyor kadar büyüktür. Örneğin,-falign-functions=32
sonraki işlevleri 32 bayt sınırının, ama-falign-functions=24
sonraki hizalama 32 bayt sınırının sadece hizalar bu az 23 byte atlanıyor tarafından yapılabilir.
-fno-align-functions
-falign-functions=1
eşdeğerdir ve fonksiyonları hizalanır.Bazı montajcıların sadece n iki güç; ne zaman bu bayrak desteği bu durumda, yuvarlanır.
N belirtilmedi veya sıfır ise, makinelere bağımlı bir varsayılan kullanın.
Düzeyleri-O2, -O3 at sağladı.
Bunu yapmak için birden çok nedeni olabilir, ama x 86 ana biri muhtemelen bu
En işlemciler 16 bayt veya 32 baytlık bloklar halinde dizilmiş talimatları getir. Olabilir kritik döngü girişleri hizalamak için avantajlı ve en aza indirmek için 16 yordam girişleri 16-bayt kod sınırları sayısı. Alternatif olarak, kritik döngü bir giriş veya yordam giriş sonra ilk birkaç talimatları 16 baytlık sınırı yoktur emin olun.
("Montaj Optimize altprogram alıntı "Sis. Agner) tarafından dil
düzenleme:Burada doldurma gösteren bir örnek:
// align.c
int f(void) { return 0; }
int g(void) { return 0; }
Varsayılan ayarlar ile gcc 4.4.5 kullanılarak derlenmiş.
align.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <f>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: b8 00 00 00 00 mov $0x0,êx
9: c9 leaveq
a: c3 retq
000000000000000b <g>:
b: 55 push %rbp
c: 48 89 e5 mov %rsp,%rbp
f: b8 00 00 00 00 mov $0x0,êx
14: c9 leaveq
15: c3 retq
-falign-functions
verir belirterek:
align.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <f>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: b8 00 00 00 00 mov $0x0,êx
9: c9 leaveq
a: c3 retq
b: eb 03 jmp 10 <g>
d: 90 nop
e: 90 nop
f: 90 nop
0000000000000010 <g>:
10: 55 push %rbp
11: 48 89 e5 mov %rsp,%rbp
14: b8 00 00 00 00 mov $0x0,êx
19: c9 leaveq
1a: c3 retq
Neden't ben PHP mysql_* fonksiyon...
Neden karma fonksiyonları bir asal say...
Neden Lambda daha düz fonksiyonları da...
Neden pthreads’ durumu değişken fonksi...
Neden üye olmayan ve C 11 fonksiyonlar...