2015-12-15 160 views
2

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

回答

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

+1

谢谢!我正试图直接跳到'ebp + 16',现在我可以看到它是错误的。另外,我并不知道'print_string'不能用于打印AL。非常感谢! – Sally

+0

是的,我看到了。你只需先取消引用[ebp + 12],然后再添加4.你知道必须添加4才能进入下一个元素。你只需要有正确的指针开始。 –

+1

@Sally我已经添加了一段关于使用缩放索引寻址的内容,您稍后可能会发现它很有用。 –