aşağıdaki C++ kaynak kod göz parçalama arızası yol açar. Ubuntu 14.04 altında 4 ve clang-3.6.0. Garip davranış, _end
sembolünün, başlangıçta değil, statik olarak ayrılmış bir dizinin _end
işaret etmesidir. _end
'u end_
ile değiştirirsek, her şey iyi çalışır.g ++ sembol '_end' kullanılması
$ g++ main.cpp -o main.s -O0 -S
$ g++ main2.cpp -o main2.s -O0 -S
$ diff main.s main2.s
1,2c1,2
< .file "main.cpp"
< .globl _end
---
> .file "main2.cpp"
> .globl end_
5,7c5,7
< .type _end, @object
< .size _end, 4200
< _end:
---
> .type end_, @object
> .size end_, 4200
> end_:
25c25
< movl $0, _end(,%rax,4)
---
> movl $0, end_(,%rax,4)
: Biz -S komut satırı argümanı sağlayarak çıkışa bir montaj kodu gcc sorarsanız
Üstelik, "_end" ve diğer dizisi adını içeren sürümü ile sürüm arasında anlamlı bir fark olacak
$ g++ main.cpp -o main -O0
$ g++ main2.cpp -o main2 -O0
$ objdump -d main >main.dump
$ objdump -d main2 > main2.dump
$ diff main.dump main2.dump
2c2
< main: формат файла elf64-x86-64 // "File format" in Russian
---
> main2: формат файла elf64-x86-64
123c123
< 4004ff: c7 04 85 c8 20 60 00 movl $0x0,0x6020c8(,%rax,4)
---
> 4004ff: c7 04 85 60 10 60 00 movl $0x0,0x601060(,%rax,4)
kadarıyla:
Ama yürütülebilir dökümü ve onlara karşı fark çalıştırmak için objdump kullanırsanız, biz _end
sürümü kullanılıyor adresi göreceksiniz gerekenden daha 4200 = 4 * 1050 bayt ileri olduğunu Biliyorum, gcc derleyici variab'ı tedavi edebilir alt çizgi ile istediği gibi başlamak, i. e. Bu, kodunuzda bu sembolleri kullanmak için kötü bir uygulamadır. Ama sorum şu: burada gerçekten ne var? Neden _end
, ayrılmış bir dizinin sonunun adresiyle değiştirilir? "-S" komut satırı argümanını kullanırsak neden bir fark olmaz, ancak oluşturulan ikili dosyalarda aslında bir fark var mı? Bu durumda gcc ve clang'ın aynı davranması değil, bu benim için de garip.
Tam olarak neye ihtiyacım vardı, teşekkürler! Fakat bu kodu derlerken neden "-S" komut satırı argümanı şüpheli görünmüyor? –
@MaximAkhmedov Muhtemelen '_end', diğer işaretçiler gibi bir işaretçi ve dizinize atandığınızda işaretçi aritmetiği gerçekleştirdiği için olabilir. – vsoftco