ここでの最初の問題は、sys_timesys呼び出しを理解する必要があることです。http://syscalls.kernelgrok.com/には、さまざまなシステムコールがレジスタへの入力として必要なものを示す便利なチャートがあります。
sys_timeはシステムコール13なので、
mov eax,13
いいね
ただし、sys_timeでは、実際の時刻を書き込むebxでメモリアドレスを渡す必要もあります。
手っ取り早い方法は、スタックにいくらかのスペースを割り当てることです(スタックに何でもプッシュできます。sys_time値がそれを上書きします。eaxの値をスタックに貼り付けてみませんか)。
push eax
次に、スタックポインタをebxにフィードします
mov ebx, esp
次に、システムコールを行います
int 80h
これで、時間をスタックから(たとえばeaxに)ポップできます。
pop eax
現在、eaxには現在のUNIX時間(つまり、1970年1月1日からの秒数)が含まれています。
UNIXコンソールに直接数値を出力するというトリッキーな作業を避けるために、nasmでコンパイルし、gccを介してcライブラリにリンクし、printfを使用する完全な例を紹介します。
[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
でコンパイル
nasm -f elf sys_time.asm
gcc sys-time.o -o sys-time
ただし、64ビットLinuxを使用している場合は、実行する必要があるかもしれません(そして、関連するmultilib gccとglibcが必要です)。このプログラムはプッシュアンドポップを使用し、32ビットレジスタを64ビットスタックにプッシュできないため、このプログラムをネイティブ64ビット実行可能ファイルとしてコンパイルすることはできません。
nasm -f elf32 sys_time.asm
gcc -m32 sys-time.o -o sys-time
次に、取得する必要があります
$ ./systime
1310190574
私はこれを32ビットと64ビットのLinuxでテストし、上記のコードをコンパイルすることができました。何か問題があれば教えてください。
nasmチュートリアルと見なされるあなたの質問に答えるために、私は最近、JeffDuntemannによる「AssemblyLanguageStep By Step、ThirdEdition」から学んでいます。詳細とサンプルの章については、http://www.duntemann.com/assembly.htmlを参照してください。