对于上下文,我在64位Debian发行版上使用NASM。
我还在学习汇编语言,这是我编写自己的编程语言的一部分,但最近我遇到了一个问题,我不知道如何处理。以下是我的编译器吐出的代码片段:
section .text
global _start
section .var_1 write
char_1 db 'Q', 0
section .var_2 write
string_1 db 'Asdf', 0
section .var_3 write
char_2 db 'W', 0
section .text
_start:
push 4 ; String length onto stack
push string_1
;; Push a raw char onto the stack
mov bl, [char_1]
push bx
pop ax
pop rbx
pop rcx
mov byte [rbx+rcx], al
如果我输出string_1
的值,我看到的是AsdfWQ
。这是因为我使用了mov
命令来进行追加,再加上我在字符串的终止字符后声明了一些数据,我一直在Google上搜索,但没有找到解决这个问题的方法(部分原因是我不知道到底要搜索什么)。从概念上讲,我认为我可以将string_1
之后的所有内容的地址移动我所附加内容的长度偏移量,但如果在此之后有40个不同的数据片段,这似乎效率非常低。我试图解决的问题是,如何管理程序集中大小可能增加或减少的动态数据?
- 编辑**
感谢fuz指出通过brk
调用进行动态内存分配是可行的,我对程序做了一些修改,但仍然遇到了一些问题:
section .var_1 write
hello_string db '', 0
section .var_2 write
again_string db 'Again!', 0
section .text
_start:
;; Get current break address
mov rdi, 0
mov rax, 12
syscall
;; Attempt to allocate 8 bytes for string
mov rdi, rax
add rdi, 8
mov rax, 12
syscall
;; Set the memory address to some label
mov qword [hello_string], rax
;; Try declaring a string
mov byte [hello_string], 'H'
mov byte [hello_string+1], 'e'
mov byte [hello_string+2], 'l'
mov byte [hello_string+3], 'l'
mov byte [hello_string+4], 'o'
mov byte [hello_string+5], ','
mov byte [hello_string+6], ' '
mov byte [hello_string+7], 0
;; Print the string
mov rsi, hello_string
mov rax, 1
mov rdx, 8
mov rdi, 1
syscall
;; Print the other string
mov rsi, again_string
mov rax, 1
mov rdx, 5
mov rdi, 1
syscall
这将导致Hello, ello,
,这意味着我仍在覆盖与again_string
标签相关的数据?但我的印象是,使用brk
进行分配将在数据初始化后进行?
1条答案
按热度按时间bejyjqdl1#
完全归功于用户
fuz
,他通过一个周末的几篇评论,帮助橡皮鸭调试正在发生的事情,同时教育了我。事实证明,不知道指针真的伤害了我对这里的理解。使用
brk
并将一段数据(如字符串)赋给标签的方法是:这个解决方案与打印
Hello, ello!
的编辑过的问题代码片段之间的主要区别在于标签的声明,当使用hello_string dq 0
时,这允许我存储rax
的内存地址,这是我分配的8字节内存的起点,然后从那里追加到8个字节。当我使用hello_string db '', 0
然后声明另一个字符串时,我只能存储一个字节,当我获得声明内存的入口点时,这个字节似乎不足以存储rax
的内存地址。