Чтение имени файла из argv через сборку x86 - PullRequest
2 голосов
/ 22 октября 2011

Я пытаюсь прочитать имя файла, переданное моему исполняемому файлу, и записать в этот файл, используя сборку. Компилируется без ошибок, но завершается с ошибкой при выполнении. Что не так с моим кодом в точности?

BITS 32
segment .data
text db "text"

segment .text

global main

main:
pop ebx 
pop ebx
pop ebx    ; pop pointer to filename into ebx
mov eax,0x5  ;syscall open
mov ecx,0x2   ;flag read/write
int 0x80   ;call kernel
mov ebx,eax   ;save returned file descriptor
mov eax,0x4 ; write syscall
mov ecx,text ;mov pointer to text into ecx
mov edx,0x4 ;string length
int 0x80  ;exit syscall
mov eax,0x1
int 0x80

Ответы [ 2 ]

5 голосов
/ 22 октября 2011

Поскольку вам звонят из libc, вы также должны помнить, что у вас есть обратный адрес, чтобы вы могли вернуться туда. Это непохоже на то, что вы получаете, если у вас есть просто программа сборки (например, множество уроков!). Имея это в виду:

pop ebx    ;; pops return address to libc caller (_start usually)
pop ebx    ;; pops argc
pop ebx    ;; pops argv !!WAS!!: ; pop pointer to filename into ebx

Вот как вы можете напечатать первый аргумент. Вы должны быть в состоянии пойти оттуда (будьте осторожны: я мог ошибиться):

    BITS 32

    section .text
    global main
    extern strlen

main:
    pop ecx ; Return address
    pop ecx ; argc
    pop ecx ; argv 
    mov ecx, [ecx+4] ; argv[1]

    push ecx
    call strlen
    mov edx, eax ; count
    pop ecx ; buf

    mov eax, 4 ; sys_write
    mov ebx, 1 ; stdout
    int 0x80

    mov eax, 1 ; sys_exit
    mov ebx, 0 ; status
    int 0x80
2 голосов
/ 22 октября 2011

При входе в main: стек имеет следующее:

...
*envp[]
*argv[]
argc
return address

Когда вы pop ebx трижды, вы в конечном итоге получаете argv, , а не argv[1].

argv - указатель на массив с нулевым символом в конце char *, поэтому вы должны следовать косвенному указанию, как показывает @ user786653.

...