NASM x86_64在编写命令行参数时遇到问题,在rax中返回-14

Kri*_*ris 2 linux 64-bit assembly x86-64 nasm

我正在使用elf64编译并尝试获取参数并将其写入控制台.

我将函数称为./test wooop

在单步执行gdb之后似乎没有问题,一切都设置好了:

rax:0x4 rbx:0x1 rcx:指向字符串,x/6cb $ rcx给出'w''o''o''o''p'0x0 rdx:0x5 <---正确确定长度

在int 80h之后,rax包含-14并且没有任何内容打印到控制台.如果我在.data中定义一个字符串,它就可以了.gdb以相同的方式显示$ rcx的值.

有任何想法吗?这是我的完整来源

    %define LF      0Ah
    %define stdout      1
    %define sys_exit    1
    %define sys_write   4


    global _start

    section .data

    usagemsg: db "test {string}",LF,0

    testmsg: db "wooop",0

    section .text

    _start:

    pop rcx     ;this is argc
    cmp rcx, 2      ;one argument
    jne usage
    pop rcx
    pop rcx               ; argument now in rcx
    test    rcx,rcx
    jz usage

    ;mov rcx, testmsg    ;<-----uncomment this to print ok!

    call print
    jmp exit


    usage:
    mov rcx, usagemsg
    call print
    jmp exit


    calclen:

    push rdi
    mov rdi, rcx
    push rcx
    xor rcx,rcx
    not rcx
    xor al,al
    cld
    repne scasb
    not rcx  
    lea rdx, [rcx-1]
    pop rcx
    pop rdi
    ret

    print:

    push rax
    push rbx
    push rdx

    call calclen

    mov rax, sys_write
    mov rbx, stdout
    int 80h
    pop rdx
    pop rbx
    pop rax
    ret

    exit:
    mov rax, sys_exit
    mov rbx, 0
    int 80h
Run Code Online (Sandbox Code Playgroud)

谢谢

编辑:改变我如何使我的系统调用如下,它工作正常.感谢你的帮助!

sys_write现在是1
sys_exit现在是60
stdout现在进入rdi,而不是rbx
写入的字符串现在在rsi中设置,而不是rcx
int 80h被syscall替换

Fra*_*ler 5

我还在运行32位硬件,所以这是一个疯狂的猜测!您可能知道,64位系统调用号完全不同,使用"syscall"而不是int 80h.但是仍然可以使用int 80h和32位系统调用号,64位寄存器被截断为32位.您的测试表明这适用于.data中的地址,但是使用"堆栈地址"时,它返回-14(-EFAULT - 错误地址).我唯一能想到的是,如果它在堆栈上,将rcx截断为ecx会导致"坏地址".我不知道堆栈在64位代码中的位置.这有意义吗?

我尝试使用"正确的"64位系统调用号码和寄存器以及"系统调用",看看是否有帮助.

最好,弗兰克