【问题标题】:NASM assembly reading file provided via command line arg通过命令行 arg 提供的 NASM 程序集读取文件
【发布时间】:2018-03-08 20:23:08
【问题描述】:

我用 NASM 程序集编写了这段代码。我想打开一个通过命令行参数提供的文件。然后我想阅读内容。不幸的是 sys_open 失败(rax 寄存器中的 file_descriptor 连接到 0xffffffffffffffffe)。当我在 .data 部分对文件名进行硬编码时 - 程序运行良好。当我通过命令行参数读取文件名时失败。感谢提示

代码:

SYS_READ    equ 0
SYS_OPEN    equ 2
SYS_CLOSE   equ 3
SYS_EXIT    equ 60
O_RDONLY    equ 0

section .bss
    argc resb 1
    filename resb 10
    array resb  256
    number resb 1
    fd resb 8 

section .text
    global _start

_start:
    pop rax              ; pop argc value - should be 2
    cmp rax, 0x2    
    jne _sys_exit_1
    pop rax              ; pop addres pointing to "./prog"
    pop rax              ; pop addres pointing to filename
    mov [filename], rax
    call _sys_open
    mov [fd], rax        ; store file descriptor

_read_seq_loop: 
    call _sys_read

    xor rbx, rbx
    mov bl, byte [number] ; store read number in bl register
    cmp bl, 0
    mov byte [array + rbx], 1 ;save it to array 
    jne _read_seq_loop

    jmp _sys_exit_0


_sys_open:
    mov rax, SYS_OPEN
    mov rdi, filename
    mov rsi, O_RDONLY
    mov rdx, 0
    syscall
    ret

_sys_read:
    mov rax, SYS_READ
    mov rdi, [fd]
    mov rsi, number
    mov rdx, 1
    syscall
    ret

_sys_exit_1:
    mov rax, SYS_EXIT
    mov rdi, 1
    syscall

_sys_exit_0:
    mov rax, SYS_EXIT
    mov rdi, 0
    syscall

【问题讨论】:

    标签: assembly nasm


    【解决方案1】:

    进行这两项更改,我想您会立即看到,不是将指针传递给字符串,而是将指针传递给指向字符串的指针。

            pop     rax              ; pop argc value - should be 2
            cmp     rax, 0x2    
            jne     _sys_exit_1
            pop    rax              ; pop addres pointing to "./prog"
            pop    rdi              ; pop address of ARG0
           call    _sys_open
            mov   [fd], rax        ; store file descriptor
    

    由于已经设置了 RDI,因此可以将其从常规中取出

    _sys_open:
            mov    rax, SYS_OPEN
            mov    rsi, O_RDONLY
            mov    rdx, 0
            syscall
            ret
    

    【讨论】:

    • 那不是 ARG0,是 argv[1]
    • @PeterCordes。 argv[1] 是一个 HLL 构造,与这种为用户传递的参数收集指针的方法无关。
    • 程序名称作为第一个参数传递只是按照惯例。调用者可以将他们想要的任何东西放在他们传递给execve(2) 的数组的第一个元素中。 re:术语:x86-64 System V ABI(图 3.9:初始进程堆栈)将其称为“参数指针”,并没有说明第一个是特殊的。但它确实使用了术语argc。无论如何,如果有人在编造高级术语,那就是您使用 ARG0。将其称为 argv[1] 很容易理解,并且 ABI 文档确实提到了 C argv 名称。
    猜你喜欢
    • 1970-01-01
    • 2018-06-20
    • 1970-01-01
    • 2021-12-05
    • 1970-01-01
    • 1970-01-01
    • 2011-03-16
    • 2023-03-27
    • 2021-06-04
    相关资源
    最近更新 更多