程序中的变量是否在内存中连续存储?

时间:2016-09-25 12:58:10

标签: c memory assembly architecture mips

我指的是下面用MIPS汇编语言编写的程序。我给不同的指令提供行号。当我理解这段代码时,我得到一个奇怪的问题。第2行(la $ a0 astringwithoutnullchar)在寄存器$ a0中加载标签“astringwithoutnullchar”的地址,当然地址指的是存储在RAM中某处的字符串,而不是在末尾有空终止符。在第3行中,进行了一个系统调用,它由操作系统子程序处理,该子程序开始在参数寄存器$ a0指定的地址处打印存储在RAM中的所有内容。现在输出的是:

 Hello1
 Hello2

这意味着子例程也打印第二个字符串,当它到达存储在第5行第二个字符串末尾的空终止符时停止打印。

我从这个输出中假设两个字符串都存储在RAM中的连续位置,因为只有这样你才能看到这个输出, 第2行存储了第一个标签的地址,该地址引用了一个内存位置,系统调用从该地址开始打印,然后递增地址以指向包含第二个字符串的下一个位置,并停止直到它到达空终止符。这是真的无论你在第一个标签“astringwithoutnullchar”之后在“.data”段中声明了多少个String标签。

现在我的问题:

程序中的变量是否连续存储在RAM中如果没有那么解释输出。我无法从谷歌得到答案,我无法在cs.stackexchange上发布这个问题,因为我指的是下面的MIPS代码。我是不要害怕细节,你可以尽可能详细地详细介绍,但每一步都有解释!

 .text

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


.data

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


OUTPUT:  Hello1
         Hello2

1 个答案:

答案 0 :(得分:0)

是的,数据在内存中是连续的。汇编器只是将字节组装到输出中。您可以将标签粘贴在任何您想要的位置,并根据需要使用它们。一切都只是字节。

以下内容相当于您的程序。

# 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" 

标签对组装到目标文件中的字节序列没有影响。它保证asm中的label:语法元素只创建标签而不修改文件位置。

这是程序集,您可以控制哪些字节进入内存。

当您的目标文件链接在一起时,某个部分中的所有内容(例如.text.data.rodata)都会保证按照您在asm中创建的方式进行布局。不保证可执行文件的text,data和bss segments 中各节的相对顺序,并且可以通过链接描述文件进行控制。

当将多个.o文件链接在一起时,每个文件都有.text,.data和.rodata部分,来自所有输入文件的所有.text部分的数据被组合在一起,但是整个块来自一个.o保持连续。 链接不会分割部分中的字节。

此问题也标有C,其中绝对不保证此类。编译器可以按照自己想要的任何顺序随意将每个单独的C对象放在任何需要的位置。如果您关心订购/连续性,请使用structchar[]。 (如果使用struct,请查阅目标平台的ABI,以了解结构成员在内存中的排序方式.C保留定义的实现。)