With A SpiRIT With A SpiRIT - 2 months ago 17
C Question

Are variables from a program stored contiguously in Memory?

I am referring to the program below written in MIPS assembly language.I have given line numbers to different instructions.When i understood this code i got a strange question. Line 2 (la $a0 astringwithoutnullchar) loads the address of the label "astringwithoutnullchar" in register $a0 now of course the address refers to the string stored somewhere in RAM, without having the null terminator at the end. In line 3 a syscall is made which is handled by the operating system sub routine which starts printing everything stored in RAM at the address specified by the argument register $a0. Now the output i get is:

Hello1
Hello2


Which means that the subroutine prints the second string also and stops printing when it reaches the null terminator stored at the end of the second string in line 5.

What i presume from this output is that both the strings are stored in contiguous locations in RAM because only then you can see this output , as
line 2 stored the address of first label which refers to a memory location and the syscall starts printing from that address and then increments the address to point to the next location which contains the second string and stops until it reaches the null terminator.This is true no matter how many String labels you declare in the ".data" segment after the first label "astringwithoutnullchar" .

NOW MY QUESTION :

Are variables from programs stored contiguously in RAM if not then explain the output.I could'nt get the answer from google and i could not post this question on cs.stackexchange as i am referring to the MIPS code below.I am not scared from the details you can go in as much detail as possible but with explanations at every step!.

.text

1>> li $v0 4
2>> la $a0 astringwithoutnullchar
3>> syscall


.data

4>> astringwithoutnullchar: .ascii "Hello1\n"
5>> astringwithnullchar: .asciiz "Hello2"


OUTPUT: Hello1
Hello2

Answer

Yes, data is contiguous in memory. Assemblers just assemble bytes into the output. You can stick labels anywhere you want, and use them however you want. Everything is just bytes.

The following is equivalent to your program.

# another way to create identical bytes in memory
section .rodata        # might as well put constants in read-only memory for efficiency.

str_unterminated:
                  .byte   'H'
                  .ascii  "ell"
                  .ascii  "o1"
label2:
                  .byte   10           # \n is ASCII 10

str_terminated:    .asciiz "Hello2" 

Labels have no effect on the sequence of bytes assembled into the object file. It's guaranteed that a label: syntax element in asm only creates the label without modifying the file position.

This is assembly, where you control what bytes go into memory.

When your object files are linked together, everything within a section (like .text, .data, or .rodata) is guaranteed to be laid out the way you created it in asm. The relative ordering of sections within the text, data, and bss segments of an executable file is not guaranteed, and can be controlled by a linker script.

When linking together multiple .o files that each have .text, .data, and .rodata sections, the data from all the .text sections from all input files is combined together, but the entire block from a single .o stays contiguous. Linking doesn't break up bytes within a section.


This question is tagged with C as well, where there are absolutely no guarantees of anything like this. The compiler is free to put each separate C object wherever it wants, in any order it wants. If you care about ordering / contiguity, then use a struct or char[]. (If you use a struct, consult the ABI for your target platform to find out how struct members are ordered in memory. C leaves this implementation defined.)