当我在程序集中声明一个字符串时:
bit_arr = bit_arr.reshape(-1, 48)
保存字符串在哪里? 我可以确定在声明时将保存的位置吗?
答案 0 :(得分:0)
db
将输出字节汇编到输出文件中的当前位置。您可以准确控制他们的去向。
没有任何其他位置的间接或引用,它就像char string[] = "blah blah"
,而不是char *string = "blah blah"
(但最后没有隐含的零字节,这就是为什么你必须使用,0
明确添加一个。)
当定位现代操作系统(即不制作引导扇区或其他东西)时,您的代码+数据将最终存储在目标文件中,然后链接到可执行文件或库中。
在Linux(或其他ELF平台)上,将包含字符串的只读常量数据放在section .rodata
中。此部分(以及放置代码的section .text
)在链接后成为文本段的一部分。
Windows显然使用section .rdata
。
不同的汇编程序有不同的语法来更改节,但我认为section .whatever
适用于使用DB
的大多数数据字节。
;; 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
10个字符是puts
的返回值,它是main的返回值,因为我们尾调用它,它成为我们程序的退出状态。 (在这种情况下,Linux glibc puts
显然会返回字符数。但是手册只是说它在成功时返回非负数,所以不要指望这一点)
I used -no-pie
because我使用string
的绝对地址mov
而不是RIP相对LEA。
您可以使用readelf -a a.out
或nm
来查看可执行文件中的位置。