汇编语言帮助找到agrv [1] [0]

sir*_*r_t 1 x86 assembly nasm argv

我正在尝试获取argv[1]x86汇编语言中存储的内容的第一个元素.我eax 最初将堆栈弹出两次,因为我想argc这样我可以计算数量argc.然后弹出argvebx.我想[ebx]进入bl.从这里我迷失了.我很少或没有组装经验,我只是想了解它.

main:
;
    mov ecx, 0 ;count output characters
    pop eax ;reject this 32 bits
    pop eax ;get argc
    ;
    pop ebx ; get argv
    ;mov bl, [ebx]
    ;
    add al, 30H ;convert integer to ascii
    mov edi, cline ;put char in output buffer
    mov byte [edi],al
    ;inc edi
    ;mov [edi], bl
    inc ecx ;increment output char count
    inc edi ;increment pointer to o/p buffer
    mov al, 0aH ;LF to end line
    mov byte[edi],al ;put it at end of output line
    inc ecx ;increment output char count
    push ecx ;save char count on stack
    mov edx,len ;length of string to write
    mov ecx,msg ;addr of string
    mov ebx,1 ;file descriptor 1 = stdout
    mov eax,4 ;"write" system call
    int 0x80 ;call the kernel
;
    pop edx ;restore char count into edx for system call
    mov ecx,cline ;address of string
    mov ebx,1 ;file descriptor 1 = stdout
Run Code Online (Sandbox Code Playgroud)

Gun*_*ner 6

看看这里:NASM - Linux获取命令行参数

下面是它的工作原理:

argc = [esp]
argv = [esp + 4 * ARG_NUMBER]
Run Code Online (Sandbox Code Playgroud)

其中ARG_NUMBER是argv的基于1的索引

./test hello there
[esp] = 3
[esp + 4 * 1] = ./test (program path and name)
[esp + 4 * 2] = hello
[esp + 4 * 3] = there
Run Code Online (Sandbox Code Playgroud)

我将使用C库中的printf使其更清晰:

extern printf, exit

section .data
fmtint  db  "%d", 10, 0
fmtstr  db  "%s", 10, 0

section .text
global main
main:

    push    dword[esp]
    push    fmtint      
    call    printf                      ; print argc
    add     esp, 4 * 2

    mov     ebx, 1  
PrintArgV:
    push    dword [esp + 4 * ebx]
    push    fmtstr
    call    printf                      ; print each param in argv
    add     esp, 4 * 2

    inc     ebx
    cmp     ebx, dword [esp]
    jng     PrintArgV

    call    exit
Run Code Online (Sandbox Code Playgroud)

这里没有错误检查以保持简单.您可以检查args的数量是否超出您的预期或其他数量.

在此输入图像描述

@Ed Cashin,如果OP正在学习INTEL语法,为什么要将它们与AT&T混淆?

  • 我建议将其写为“[esp + 4 + 4 * ARG_INDEX]”,这样您就不必混乱从 1 开始的编号。然后一切都与 C 匹配,其中“argv[1]”是程序名称后的第一个参数。 (2认同)