【发布时间】:2018-06-07 13:53:20
【问题描述】:
我正在尝试使用sys_brk 系统调用在linux 中分配一些内存。这是我尝试过的:
BYTES_TO_ALLOCATE equ 0x08
section .text
global _start
_start:
mov rax, 12
mov rdi, BYTES_TO_ALLOCATE
syscall
mov rax, 60
syscall
根据 linux 调用约定,我希望返回值在rax 寄存器中(指向分配内存的指针)。我在 gdb 中运行它,在进行 sys_brk 系统调用后,我注意到以下寄存器内容
系统调用之前
rax 0xc 12
rbx 0x0 0
rcx 0x0 0
rdx 0x0 0
rsi 0x0 0
rdi 0x8 8
系统调用后
rax 0x401000 4198400
rbx 0x0 0
rcx 0x40008c 4194444 ; <---- What does this value mean?
rdx 0x0 0
rsi 0x0 0
rdi 0x8 8
在这种情况下,我不太了解rcx 寄存器中的值。哪个用作指向我用sys_brk 分配的8 个字节开头的指针?
【问题讨论】:
-
RCX 和 R11 被 SYSCALL 指令本身所破坏。来自指令集参考:将 SYSCALL 之后的指令地址保存到 RCX 之后)。 RFLAGS 被存储到 R11
-
@MichaelPetch 非常有趣。这意味着为了使用,说
cl之后注册我需要先清除它,对吗?我的意思是例如xor cl, cl,然后是mov cl, 7。 -
您不能依赖 SYSCALL 之后的 RCX 或 R11 的值。因此,您必须使用其他寄存器之一而不是 RCX 和 R11 (和 RAX),或者您必须保存值(例如堆栈)和之后恢复它。 RCX 和 R11 不是由你设置的,你只是不能使用它们并期望它们在 SYSCALL 之前和之后是相同的。
-
@MichaelPetch 但是只清除有什么问题?
-
之前清除它会被 SYSCALL 覆盖。 SYSCALL 只会覆盖其中的内容。如果您愿意,您可以在 SYSCALL 之后设置它,但如果您执行另一个 SYSCALL,则该值将被破坏。
标签: linux assembly x86-64 system-calls