1

ASM(NASM)を使い始めたばかりで、次のスニペットについてサポートが必要です。エラー/警告は表示されません。何も出力されません。私が期待していたのは、時間を取得し(13)、それを印刷して(4)、終了する(1)ことでした。また、誰かがいくつかの良い(できればNASM固有の)ASMチュートリアルを知っていますか?

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
4

2 に答える 2

6

ここでの最初の問題は、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を参照してください。

于 2011-07-09T17:13:19.860 に答える
3

これはCに変換された例です。バッファへのeaxではなくeaxへのtimeへのポインタをコピーしています。それでも、ガベージを出力する生の整数ではなく、書き込み用の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);
}
于 2009-08-07T01:59:43.360 に答える