First, I do understand that using global data is usually a bad idea, but I want to explain the mechanism of global data to students. I'm using gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1) for x86-64 code. I'm looking at how global variables are handled in position independent code. Test program: int x = 12; int y = 34; int z; int main(void) { z = x + y; printf("%i + %i = %i\n", x, y, z); return 0; } Why does gcc emit an extra .text before the global data? .file "globalData.c" .text .globl x .data .align 4 .type x, @object .size x, 4 x: .long 12 .globl y .align 4 .type y, @object .size y, 4 y: .long 34 .comm z,4,4 .section .rodata .LC0: .string "%i + %i = %i\n" .text .globl main .type main, @function main: I can remove the .text at the beginning, .file "globalData.c" .globl x .data .align 4 .type x, @object .size x, 4 x: .long 12 .globl y .align 4 .type y, @object .size y, 4 y: .long 34 .comm z,4,4 .section .rodata .LC0: .string "%i + %i = %i\n" .text .globl main .type main, @function main: and readelf shows that the assembler, as, produces exactly the same object file. I can even see that .comm and .section .rodata do not need to be within a .text or .data region, .file "globalData.c" .comm z,4,4 .section .rodata .LC0: .string "%i + %i = %i\n" .globl x .data .align 4 .type x, @object .size x, 4 x: .long 12 .globl y .align 4 .type y, @object .size y, 4 y: .long 34 .text .globl main .type main, @function main: Assembly and using readelf shows that they are only reordered but are in the same sections in the object file.