1

我在理解汇编中更复杂的系统调用时遇到了一些麻烦。我写了一个 exec 系统调用,效果很好

 .bss

.text

.globl _start

_start:

#exit(0) system call

        movl $1, %rax
        movl $0, %rbx
        int $0X80

虽然我有点保证并且无法找到有关如何将字符串放入寄存器的信息。所以作为一个例子,我想做一个 exec 系统调用,它作为它的第一个参数需要一个文件名来运行,我想运行“/bin/bash”,但是我如何在 rbx 中得到它。我怎么知道我必须使用rbx,在X86中我知道我会使用ebx,在amd64 ebx = rbx,ecx = rcs等中是否有相同的关系?

int execve(const char *filename, char *const argv[], char *const envp[]);

谢谢大家

4

2 回答 2

4

这里有一个技巧可以在汇编的这些方面快速取得进展:请 C 编译器向您展示它是如何做到的!编写一个 C 程序来执行您想做的事情并键入gcc -S.

例子:

Manzana:ppc pascal$ cat t.c
#define NULL ((void*)0)
char *args[] = { "foo", NULL } ;
char *env[] = { "PATH=/bin", NULL } ;


int execve(const char *filename, char *const argv[], char *const envp[]);

int main()
{

  execve("/bin/bash", args, env);

} 

然后:

Manzana:ppc pascal$ gcc -S -fno-PIC t.c  # added no-PIC for readability of generated code
Manzana:ppc pascal$ cat t.s
.globl _args
    .cstring
LC0:
    .ascii "foo\0"
    .data
    .align 2
_args:
    .long   LC0
    .long   0
.globl _env
    .cstring
LC1:
    .ascii "PATH=/bin\0"
    .data
    .align 2
_env:
    .long   LC1
    .long   0
    .cstring
LC2:
    .ascii "/bin/bash\0"
    .text
.globl _main
_main:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $24, %esp
    movl    $_env, 8(%esp)
    movl    $_args, 4(%esp)
    movl    $LC2, (%esp)
    call    _execve
    leave
    ret
    .subsections_via_symbols
于 2009-11-20T21:18:56.807 回答
3

您不会将字符串放入寄存器中。您应该在此函数的寄存器中将指针(地址)传递给以空 (0) 结尾的字符串(C 风格)。一些系统调用(如write)在两个寄存器中采用指针(不一定由 终止'\0')和长度。

# somewhere in the data section:
myString:
   .asciz "/bin/bash"

$myString使用寄存器通过。

于 2009-11-20T21:13:27.857 回答