String 常量字符串保存在程序集中的什么位置?

String 常量字符串保存在程序集中的什么位置?,string,assembly,memory,x86,String,Assembly,Memory,X86,当我在程序集中声明字符串时,如下所示: string DB "My string", 0 字符串保存在哪里? 声明它时,我可以确定它将保存在哪里吗?db将输出字节汇编到输出文件中的当前位置。您可以精确控制它们的去向 没有对任何其他位置的间接或引用,这就像char string[]=“blah blah”,而不是char*string=“blah blah”(但结尾没有隐式的零字节,这就是为什么必须使用,0来显式添加一个。) 当针对现代操作系统时(即不制作引导扇区或其他东西),您的代码+数据将

当我在程序集中声明字符串时,如下所示:

string DB "My string", 0
字符串保存在哪里?
声明它时,我可以确定它将保存在哪里吗?

db
将输出字节汇编到输出文件中的当前位置。您可以精确控制它们的去向

没有对任何其他位置的间接或引用,这就像
char string[]=“blah blah”
,而不是
char*string=“blah blah”
(但结尾没有隐式的零字节,这就是为什么必须使用
,0
来显式添加一个。)


当针对现代操作系统时(即不制作引导扇区或其他东西),您的代码+数据将最终保存在目标文件中,然后链接到可执行文件或库中

在Linux(或其他ELF平台)上,将只读常量数据(包括字符串)放入
部分。rodata
。链接后,此部分(以及放置代码的
部分.text
)成为文本段的一部分

Windows显然使用了
section.rdata

不同的汇编器有不同的语法来更改节,但我认为
节。在大多数使用
DB
来处理数据字节的汇编器中,任何
都可以工作



10个字符是来自
put
的返回值,这是来自main的返回值,因为我们tail调用了它,它成为我们程序的退出状态。(Linux glibc
put
显然在这种情况下返回字符计数。但手册只说它在成功时返回非负数,所以不要指望这个)

我用
string
mov
的绝对地址代替了RIP相对LEA



您可以使用
readelf-a.out
nm
查看可执行文件中的内容。

db
将输出字节汇编到输出文件中的当前位置。您可以精确控制它们的去向

没有对任何其他位置的间接或引用,这就像
char string[]=“blah blah”
,而不是
char*string=“blah blah”
(但结尾没有隐式的零字节,这就是为什么必须使用
,0
来显式添加一个。)


当针对现代操作系统时(即不制作引导扇区或其他东西),您的代码+数据将最终保存在目标文件中,然后链接到可执行文件或库中

在Linux(或其他ELF平台)上,将只读常量数据(包括字符串)放入
部分。rodata
。链接后,此部分(以及放置代码的
部分.text
)成为文本段的一部分

Windows显然使用了
section.rdata

不同的汇编器有不同的语法来更改节,但我认为
节。在大多数使用
DB
来处理数据字节的汇编器中,任何
都可以工作



10个字符是来自
put
的返回值,这是来自main的返回值,因为我们tail调用了它,它成为我们程序的退出状态。(Linux glibc
put
显然在这种情况下返回字符计数。但手册只说它在成功时返回非负数,所以不要指望这个)

我用
string
mov
的绝对地址代替了RIP相对LEA



您可以使用
readelf-a.out
nm
查看可执行文件中的内容。

您的代码将告诉您它将在哪里。根据汇编程序的不同,有不同的方法。你能详细说明一下标题中的“const strings”和问题中的字节声明(这只是定义字节值;没有特别的方式显示“const”特性)是什么意思吗。若在公共数据段中的公共程序集中执行该操作,则可以在运行时修改该内存。x86上的运行时“const”是通过将内存布局组织到不同的页面中,并将包含“const”数据的页面设置为只读访问来实现的。也可以只存在编译时“const”,比如MASM,或者两者都存在,比如C/C++。不清楚你在问什么。@Ped7g他不能简单地写
mov-si,offset-string
si寄存器将存储字符串的偏移量。现在有了DS:SI寄存器,他可以在内存中找到他的字符串。@Ahtisham是的,你可以通过TASM/MASM中的地址来获得内存地址。但这并没有说明在源代码编写过程中声明它的地方。实际上,您可以通过在源代码中的适当位置声明字符串,来有意地定位字符串在二进制文件中“land”的位置。如果你想把它放在“数据”部分,你必须在“数据”部分声明它,等等。。。作为程序员,您可以(几乎)完全控制从汇编程序发出的机器代码,因此您可以通过在源代码的所需部分声明来确定将保存到哪里。要得到它的确切地址就是这么简单的
mov
。@Ahtisham不,你在回答别的问题,而不是OPs问题。您的指令在运行时获取地址。OP的问题是,如何有意识地设计,数据将“降落”在二进制中的什么位置,以及是否有可能影响到这一点(至少我是这样理解这个问题的,它不是很清楚)。您的代码将告诉它将在哪里。根据汇编程序的不同,有不同的方法。你能详细说明一下标题中的“const strings”和问题中的字节声明(这只是定义字节值;没有特别的方式显示“const”特性)是什么意思吗。若在公共数据段中的公共程序集中执行该操作,则可以在运行时修改该内存。x86上的运行时“const”是通过将内存布局组织到不同的页面中,并将包含“const”数据的页面设置为只读访问来实现的。也可以只存在编译时“const”,就像MASM一样,
;; NASM source for the x86-64 System V ABI.

section .rodata            ; use section .rdata on Windows
string DB "My string", 0

section .data
static_storage_for_something: dd 123    ; one dword with value = 123
;; usually you don't need .data and can just use registers or the stack

section .bss                 ; zero-initialized memory, bytes not stored in the executable, just size
static_array: resd 12300000       ;; 12300000 dwords with value = 0

section .text
extern puts     ; defined in libc

global main
main:
    mov   edi, string      ; RDI = address of string = first function arg
    ;mov  [rdi], 1234      ; would segfault because .rodata is mapped read-only
    jmp   puts             ; tail-call puts(string)
peter@volta:/tmp$ cat > string.asm
  (and paste the above, then press control-D)
peter@volta:/tmp$ nasm -f elf64 string.asm  && gcc -no-pie string.o && ./a.out
My string
peter@volta:/tmp$ echo $?
10