2009-08-06 9 views
1

私はASM(NASM)を使い始めました。次のスニペットで助けが必要です。私はエラー/警告を受け取りません。何も出力しません。私が期待していたのは、それが時間を得て(13)、次にそれを印刷して(4)、次に出口(1)でした。また、誰かが良い(好ましくはNASM固有の)ASMチュートリアルを知っていますか?NASMプリントアウトタイムコードは何も出力しません

section .bss 
    time: resb 255 

section .text 
    global _start 

_start: 
    mov eax, 13 
    int 0x80 
    mov eax, time 

    mov edx, 255 
    mov ecx, time 
    mov ebx, 1 
    mov eax, 4 
    int 0x80 

    mov eax, 1 
    int 0x80 
+2

自分を打ち負かさないでください。すべてのアセンブリはひどいです。 ;) –

+0

あなたが作業しているプラ​​ットフォームについて言及する価値があるかもしれません。 –

+0

私はNASMで64ビットLinuxに取り組んでいます。 – kylc

答えて

3

この例は、Cに翻訳されています。ポインタをバッファにeaxではなくeaxにコピーしています。それでも、書き込み用のchar配列と不要な文字を出力する生の整数を必要としないので、うまくいきません。

#include <stdlib.h> 

char b[255]; 

int 
main() 
{ 
     /* You wanted to do this which doesn't work 
     * because write wont take int* but char arrays 
     * *(int*)b=time(NULL); 
     */ 

     /* Instead you did */ 
     time(NULL); 
     b; 
     write(1, b, 255); 
     exit(1); 
} 
6

ここでの最初の問題は、sys_time sys呼び出しを理解することです。 http://syscalls.kernelgrok.com/には、さまざまなsys呼び出しがレジスタに入力として必要とするものを示す便利な図があります。

SYS_TIMEはそう

mov eax,13 

しかしSYS_TIMEも、それが実際の時刻を書き込み、EBXに渡されるメモリアドレスを、必要と

良いですが、システムコール13です。

すばやくスタックにスペースを割り当てることができます(スタック上の何かを押すことができます。sys_timeの値は上書きされます)。

push eax 

そして、今、システムコール

int 80h 

は、今、私たちは

(例えば、EAXに)スタックからの時間を開くことができ作るEBX

mov ebx, esp 

にスタックポインタを養います

pop eax 

現在、eaxにはcurレンタルユニックス時間(すなわち、 1月1日1970年からの秒数)

私はgccを介して、NASMとCライブラリとリンクしてコンパイルされ、printfの

を使用する完全な例をカンニングして提供するUNIXコンソールに直接印刷番号のtrickynessを避けるために

nasm -f elf sys_time.asm 
gcc sys-time.o -o sys-time 

[SECTION .data] 
PrintNum db "%d",10,0 ;this is a c string so is null terminated 
[SECTION .text] 
extern printf  
global main 

main: 
     push ebp 
    mov ebp,esp 
    push ebx 
    push esi 
    push edi  ; stuff before this for glibc compatibility 

    mov eax, 13 
    push eax 
    mov ebx, esp 
    int 0x80 
    pop eax 

    push eax  ; push eax onto stack then the format string, then call printf to write eax to console, unwind stack pointer 
    push PrintNum 
    call printf 
    add esp,8 


    pop edi   ; stuff after this for glibc compatibility 
    pop esi 
    pop ebx 
    mov esp,ebp 
    pop ebp 
    ret 

コンパイルあなたは、64ビットのLinux上にある場合、あなたは何をする必要があり(および関連するmultilibののgccとglibcのを持っている)かもしれないが。プッシュとポップを使用し、32ビットレジスタを64ビットスタックにプッシュできないため、このプログラムをネイティブの64ビット実行可能ファイルとしてコンパイルすることはできません。

nasm -f elf32 sys_time.asm 
gcc -m32 sys-time.o -o sys-time 

次に、あなたは、私が32ビットと64ビットのLinux上でこれをテストし、コンパイル済みの上記のコードを得ることができました

$ ./systime 
1310190574 

取得する必要があります。何か問題がある場合は教えてください。

あなたの疑問にお答えするために、私は最近、Jeff Duntemannの "Assembly Language Step By Step、第3版"から学びました。詳細およびサンプルの章については、http://www.duntemann.com/assembly.htmlを参照してください。

関連する問題