打印第二个命令行参数 [英] Print 2nd command line argument

查看:76
本文介绍了打印第二个命令行参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个代码,该代码可以打印出程序的第二个参数.我知道ebp+8保留参数的数量,ebp+12保留程序名称的地址,依此类推.到目前为止,我有:

%include "asm_io.inc"

SECTION .data
err1: db "Incorrect number of command line arguments",10,0

SECTION .text 
    global  asm_main

asm_main:
   enter 0,0
   pusha

   mov eax, dword [ebp+8]
   cmp eax, dword 2
   jne ERR1

   mov eax, dword [ebp+16]  ; prints 1st letter of 2nd argument
   mov al, byte[eax]
   call print_string
   jmp asm_main_end


 ERR1:
   mov eax, err1
   call print_string
   jmp asm_main_end

 asm_main_end:
   call print_nl
   popa                  ; restore all registers
   leave                     
   ret

可执行文件称为 lynarr .当我执行lynarr abcd时,我可以打印程序名称(即 lynarr ),但是我不知道如何打印第二个参数.我正在使用redhat-linux和nasm 2.10.07.有任何想法吗?

解决方案

dword [ebp+12]是指向字符串指针数组的指针.该数组的第一个元素是指向第一个字符串的指针,第二个元素是指向第二个字符串的指针,等等.每个指针的宽度为32位(4字节).

要获取指向第二个字符串的指针,将需要将指针指向dword [ebp+12] + 4.您不能直接在x86寻址中执行此操作.您可以通过将dword [ebp+12]移至 EAX 这样的寄存器中,并向其添加4(因为指针为4字节宽),然后对其进行取消引用以获得第二个字符串的指针来做到这一点.

替换:

mov eax, dword [ebp+16]  ; prints 1st letter of 2nd argument
mov al, byte[eax]
call print_string

使用:

mov eax, dword [ebp+12]  
mov eax, [eax+4]          ; EAX = pointer to 2nd argument
call print_string

这将打印出第二个参数.第一个参数可以使用以下命令打印出来:

mov eax, dword [ebp+12]  
mov eax, [eax]           ; EAX = pointer to 1st argument
call print_string

当然mov eax, [eax+8]会得到第三个参数,依此类推.

您不能使用print_string在寄存器中打印单个字符(例如 AL ). EAX 必须是指向 NUL (\ 0)终止的字符串的指针.


您还可以使用缩放索引寻址逐步遍历数组(如您的参数):

mov ebx, dword [ebp+12]  
xor esi, esi            ; Index of first argument (index=0) 
mov eax, [ebx+esi*4]    ; EAX = pointer to 1st argument
call print_string
inc esi                 ; Next argument (index=1)
mov eax, [ebx+esi*4]    ; EAX = pointer to 2nd argument
call print_string
inc esi                 ; Next argument (index=2)
mov eax, [ebx+esi*4]    ; EAX = pointer to 3rd argument
call print_string

有了这个主意,您可能会看到如何创建一个遍历参数的循环.我把它留给读者作为练习.这是另一个方便的

The executable is called lynarr. When I execute lynarr abcd, I'm able to print the program name (ie lynarr) but I don't understand how to print the 2nd argument. I'm using redhat-linux and nasm 2.10.07. Any ideas?

dword [ebp+12] is a pointer to an array of string pointers. The first element of that array is a pointer to the first string, the second element is a pointer to the second string etc. Each pointer is 32-bits (4 bytes) wide.

To get a pointer to the second string would require getting the pointer at dword [ebp+12] + 4. You can't do that directly in x86 addressing. You can do it by moving dword [ebp+12] into a register like EAX, add 4 to it (since a pointer is 4 bytes wide) and then dereference that to get a pointer of the second string.

Replace:

mov eax, dword [ebp+16]  ; prints 1st letter of 2nd argument
mov al, byte[eax]
call print_string

With:

mov eax, dword [ebp+12]  
mov eax, [eax+4]          ; EAX = pointer to 2nd argument
call print_string

This would print out the second argument. The first argument can be printed out with:

mov eax, dword [ebp+12]  
mov eax, [eax]           ; EAX = pointer to 1st argument
call print_string

Of course mov eax, [eax+8] would get the 3rd argument and so on.

You can't use print_string to print a single character in a register (like AL). EAX must be a pointer to a NUL(\0) terminated string.


Something else you can do is use scaled index addressing to step through an array (like your arguments):

mov ebx, dword [ebp+12]  
xor esi, esi            ; Index of first argument (index=0) 
mov eax, [ebx+esi*4]    ; EAX = pointer to 1st argument
call print_string
inc esi                 ; Next argument (index=1)
mov eax, [ebx+esi*4]    ; EAX = pointer to 2nd argument
call print_string
inc esi                 ; Next argument (index=2)
mov eax, [ebx+esi*4]    ; EAX = pointer to 3rd argument
call print_string

With this idea you can probably see how you can create a loop that goes through the arguments. I leave that as an exercise for the reader. This is another handy quick reference for addressing modes.

这篇关于打印第二个命令行参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆