打印第二个命令行参数

时间:2015-12-15 06:26:40

标签: assembly x86 command-line-arguments nasm 32-bit

我正在编写一个打印出程序第二个参数的代码。我理解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。有任何想法吗?

1 个答案:

答案 0 :(得分:4)

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)终止字符串的指针。

你可以做的其他事情就是使用scaled index addressing来遍历一个数组(比如你的参数):

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

有了这个想法,你可以看到如何创建一个遍历参数的循环。我把它作为读者的练习。这是解决模式的另一个方便quick reference

相关问题