我指的是下面用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
答案 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对象放在任何需要的位置。如果您关心订购/连续性,请使用struct
或char[]
。 (如果使用struct
,请查阅目标平台的ABI,以了解结构成员在内存中的排序方式.C保留定义的实现。)