2011-10-21 9 views
2

私は実行ファイルに渡されたファイル名を読み込み、アセンブリを使用してそのファイルに書き込もうとしています。それはエラーなしでコンパイルされますが、実行すると失敗します。私のコードで何が間違っていますか?あなたはあなたのlibcから呼び出されているのでargvからx86アセンブリ経由でファイル名を読み取る

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 
+0

あなたは4バイト文字列(文字列はアセンブリで自動的にゼロ終了しない)から5バイトを書いています。 – user786653

+0

コードを転記する前にそのビットを変更するのを忘れました。テキスト文字列を変更しました。 – evanjs

+0

別のこと:ファイル名に 'argv [0]'と同じCを使用していませんか? – user786653

答えて

5

はまた、あなたがそこに戻ることができるようにあなたがリターンアドレスを持っていることを思い出す必要があります。これはベアボーンのアセンブリプログラム(多くのチュートリアルのようなもの)を持っている場合とは異なります。これを念頭に置いて:

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 
+0

ありがとうございました。あなたの答えは非常に高く評価されます。 – evanjs

2

メインへのエントリ上:スタックには、以下があります。

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

ときあなたは三度pop ebx、あなたは終了しますargv,argv[1]ではありません。

argvはNULL終端された配列char *へのポインタであるため、@ user786653が示すように間接指示に従わなければなりません。