打印命令行参数 x86 程序集

0 linux assembly nasm

首先,我是汇编新手,但在 C++ 方面有不错的背景。我的问题源于我使用 assembly关注命令行参数的教程。

当程序运行时,它会根据教程执行它应该做的一切,即显示程序输入列表: ./asm1 arg1 arg2 arg3

问题是当您提供星号作为参数时: ./asm1 *

它有效地在 CWD 上执行/usr/bin/ls

我的问题是如何防止这种情况发生,以及有关实施该计划的更好方法的任何建议。

替换:

; the loop
        cmp ecx, eax        ; if ecx not equal to eax
        jne begin_for_loop  ; jmp to loop, else exit
Run Code Online (Sandbox Code Playgroud)

和:

; the loop
         cmp ecx, eax        ; if ecx not equal to eax
         jmp begin_for_loop  ; jmp to loop, else exit
Run Code Online (Sandbox Code Playgroud)

我发现了一个更大的问题,即程序将 ENV 变量打印到屏幕上。

这是下面的原始程序:

; FOR LOOP: Print commandline arguments> an equivalent program to 
this in assembly
SECTION .data

    argv db "Arguments = %s",10,0
    argc db "Argument Count = %d",10,0

SECTION .text
; allow access to printf
extern printf
; make main_function available externally
global main


main:    ; int main (int argc, char* argv[])
    push ebp
    mov ebp,esp
    sub esp, 10

    mov eax, DWORD [ebp + 8]    ; points to argc
    mov ebx, DWORD [ebp + 12]   ; points to argv
    mov ecx, 0      ; mov ZERO to count register

begin_for_loop:
    ; always preserve values prior to external function calls
    ; external function calls may modify values you placed in registers
    push ebx    ; preserve ebx; holds argument address
    push eax    ; preserve eax; holds number of arguments
    push ecx    ; preserve ecx; holds the counter

    ; call printf
    push DWORD [ebx]
    push argv
    call printf
    add esp, 8  ; clean up the stack

    ; always restore in backwards order
    pop ecx     ; restore counter
    pop eax     ; restore number of arguments
    pop ebx     ; restore argument address

    inc ecx     ; increase our counter by 1
    add ebx, 4  ; move to next argument in the array

    ; the loop
    cmp ecx, eax        ; if ecx not equal to eax
    jne begin_for_loop  ; jmp to loop, else exit


    mov esp,ebp
    pop ebp
    ret
Run Code Online (Sandbox Code Playgroud)

预期输出:

$ ./asm5 me you them us
Arguments = ./asm5
Arguments = me
Arguments = you
Arguments = them
Arguments = us
Run Code Online (Sandbox Code Playgroud)

有问题的输出:

$ ./asm5 me you them us *
Arguments = ./asm5
Arguments = me
Arguments = you
Arguments = them
Arguments = us
Arguments = asm1
Arguments = asm1.asm
Arguments = asm1.o
Arguments = asm2
Arguments = asm2.asm
Arguments = asm3
Arguments = asm3.asm
Arguments = asm4
Arguments = asm4.asm
Arguments = asm5
Arguments = asm5.asm
Arguments = asm-template.asm
Arguments = compile-asm.sh
Arguments = cpp_libs
Run Code Online (Sandbox Code Playgroud)

Mat*_*lia 5

在 POSIX 系统上,如果你从 shell 启动一个程序,shell将执行所谓的 globbing,扩展*并用匹配的文件替换它;结果将用作调用程序的参数。

你不能做任何事情来阻止它出现在你的程序中,你看到的参数确实是从 shell 获得的参数(IOW,它们是传递给 的参数exec)。

如果要在*从 shell 启动程序时将文字传递给程序,则必须引用它。

./asm5 me you them us "*"
Run Code Online (Sandbox Code Playgroud)

当然,如果其他程序启动您的程序将参数直接传递给exec,而没有外壳妨碍,则这一切都不会发生。


替换:

; the loop
         cmp ecx, eax        ; if ecx not equal to eax
         jne begin_for_loop  ; jmp to loop, else exit
Run Code Online (Sandbox Code Playgroud)

和:

; the loop
         cmp ecx, eax        ; if ecx not equal to eax
         jmp begin_for_loop  ; jmp to loop, else exit
Run Code Online (Sandbox Code Playgroud)

我发现了一个更大的问题,即程序将 ENV 变量打印到屏幕上。

这是因为您忽略了终止argv参数列表的 NULL ,并且您继续阅读接下来的内容;在您的情况下,这恰好是环境内存块。