程序中的变量是否连续存储在内存中?
Are variables from a program stored contiguously in Memory?
我指的是下面用 MIPS 汇编编写的程序 language.I 已经给了不同的行号 instructions.When 我理解这段代码我遇到了一个奇怪的问题。第 2 行 (la $a0 astringwithoutnullchar) 将标签 "astringwithoutnullchar" 的地址加载到寄存器 $a0 中,当然该地址是指存储在 RAM 中某处的字符串,末尾没有空终止符。在第 3 行中,系统调用由操作系统子例程处理,该子例程开始打印存储在 RAM 中由参数寄存器 $a0 指定的地址的所有内容。现在我得到的输出是:
Hello1
Hello2
这意味着子例程也打印第二个字符串,并在到达存储在第 5 行第二个字符串末尾的空终止符时停止打印。
我从这个输出中推测这两个字符串都存储在 RAM 中的连续位置,因为只有这样你才能看到这个输出,因为
第 2 行存储了指向内存位置的第一个标签的地址,系统调用从该地址开始打印,然后递增地址以指向包含第二个字符串的下一个位置并停止,直到它到达 null terminator.This无论您在第一个标签 "astringwithoutnullchar" .
之后的“.data”段中声明了多少字符串标签,都是如此
现在我的问题是:
程序中的变量是否连续存储在 RAM 中,如果不是,请解释 output.I 无法从 google 得到答案,我无法 post [=28] 上的这个问题=] 因为我指的是 MIPS 代码 below.I 我并不害怕细节,你可以尽可能详细,但每一步都有解释!
.text
1>> li $v0 4
2>> la $a0 astringwithoutnullchar
3>> syscall
.data
4>> astringwithoutnullchar: .ascii "Hello1\n"
5>> astringwithnullchar: .asciiz "Hello2"
OUTPUT: Hello1
Hello2
是的,数据在内存中是连续的。汇编程序只是 assemble 字节到输出中。您可以将标签贴在任何地方,并随心所欲地使用它们。一切都只是字节。
以下等同于你的程序
# 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"
标签对目标文件中assembled字节的顺序没有影响。保证asm中的label:
语法元素只创建不修改文件位置的标签。
这是程序集,您可以在其中控制哪些字节进入内存。
当您的目标文件链接在一起时,一个部分中的所有内容(如 .text
、.data
或 .rodata
)保证按照您在其中创建它的方式进行布局汇编无法保证可执行文件的文本、数据和 bss 段 中节的相对顺序,可以通过链接器脚本控制。
当将多个 .o
文件链接在一起时,每个文件都有 .text、.data 和 .rodata 部分,来自所有输入文件的所有 .text 部分的数据组合在一起,但整个块来自单个 .o 保持连续。 链接不会在节内打散字节。
这个问题也用 C 标记,其中绝对不能保证像这样的事情。编译器可以自由地将每个单独的 C 对象放在任何它想要的地方,以任何它想要的顺序。如果您关心顺序/连续性,请使用 struct
或 char[]
。 (如果您使用 struct
,请查阅您的目标平台的 ABI 以了解结构成员在内存中的排序方式。C 保留此实现定义。)
我指的是下面用 MIPS 汇编编写的程序 language.I 已经给了不同的行号 instructions.When 我理解这段代码我遇到了一个奇怪的问题。第 2 行 (la $a0 astringwithoutnullchar) 将标签 "astringwithoutnullchar" 的地址加载到寄存器 $a0 中,当然该地址是指存储在 RAM 中某处的字符串,末尾没有空终止符。在第 3 行中,系统调用由操作系统子例程处理,该子例程开始打印存储在 RAM 中由参数寄存器 $a0 指定的地址的所有内容。现在我得到的输出是:
Hello1
Hello2
这意味着子例程也打印第二个字符串,并在到达存储在第 5 行第二个字符串末尾的空终止符时停止打印。
我从这个输出中推测这两个字符串都存储在 RAM 中的连续位置,因为只有这样你才能看到这个输出,因为 第 2 行存储了指向内存位置的第一个标签的地址,系统调用从该地址开始打印,然后递增地址以指向包含第二个字符串的下一个位置并停止,直到它到达 null terminator.This无论您在第一个标签 "astringwithoutnullchar" .
之后的“.data”段中声明了多少字符串标签,都是如此现在我的问题是:
程序中的变量是否连续存储在 RAM 中,如果不是,请解释 output.I 无法从 google 得到答案,我无法 post [=28] 上的这个问题=] 因为我指的是 MIPS 代码 below.I 我并不害怕细节,你可以尽可能详细,但每一步都有解释!
.text
1>> li $v0 4
2>> la $a0 astringwithoutnullchar
3>> syscall
.data
4>> astringwithoutnullchar: .ascii "Hello1\n"
5>> astringwithnullchar: .asciiz "Hello2"
OUTPUT: Hello1
Hello2
是的,数据在内存中是连续的。汇编程序只是 assemble 字节到输出中。您可以将标签贴在任何地方,并随心所欲地使用它们。一切都只是字节。
以下等同于你的程序
# 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"
标签对目标文件中assembled字节的顺序没有影响。保证asm中的label:
语法元素只创建不修改文件位置的标签。
这是程序集,您可以在其中控制哪些字节进入内存。
当您的目标文件链接在一起时,一个部分中的所有内容(如 .text
、.data
或 .rodata
)保证按照您在其中创建它的方式进行布局汇编无法保证可执行文件的文本、数据和 bss 段 中节的相对顺序,可以通过链接器脚本控制。
当将多个 .o
文件链接在一起时,每个文件都有 .text、.data 和 .rodata 部分,来自所有输入文件的所有 .text 部分的数据组合在一起,但整个块来自单个 .o 保持连续。 链接不会在节内打散字节。
这个问题也用 C 标记,其中绝对不能保证像这样的事情。编译器可以自由地将每个单独的 C 对象放在任何它想要的地方,以任何它想要的顺序。如果您关心顺序/连续性,请使用 struct
或 char[]
。 (如果您使用 struct
,请查阅您的目标平台的 ABI 以了解结构成员在内存中的排序方式。C 保留此实现定义。)