2009-08-06 83 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

不要打垮自己。所有集會都很糟糕。 ;) – 2009-08-06 23:21:27

+0

可能值得提及您正在使用的平臺。 – 2009-08-06 23:57:20

+0

我正在與64位Linux和NASM合作。 – kylc 2009-08-07 00:02:01

回答

3

這是您的示例翻譯爲C.您正在將指針複製到eax而不是eax到緩衝區。仍然不會工作,因爲你想要一個字符數組進行寫入,而不是一個會打印垃圾的原始整數。

#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是系統調用13,所以

mov eax,13 

然而SYS_TIME還要求EBX傳遞一個內存地址,它寫的實際時間。

一個快速的方法是在堆棧上分配一些空間(我們可以在堆棧上推動任何東西,sys_time值會覆蓋它,爲什麼不把它的值附加到堆棧上)。

push eax 

然後喂堆棧指針到EBX

mov ebx, esp 

現在使系統調用

int 80h 

現在我們可以彈出時間從堆棧(進入如EAX)

pop eax 

現在eax包含cur租用unix時間(即自1月1日1970年)的秒數

避免直接打印數字的trickyness到UNIX控制檯我會欺騙,並提供通過GCC編譯在NASM,並與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)。您無法將此程序編譯爲本機64位可執行文件,因爲它使用推送和彈出方式,並且無法將32位寄存器推送到64位堆棧。

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

那麼你應該得到

$ ./systime 
1310190574 

我在32位和64位Linux測試這一點,並設法編譯上面的代碼。如果您有任何問題,請告訴我。

爲了回答你關於nasm教程的問題,我最近從Jeff Duntemann的「Assembly Language Step By Step,Third Edition」中學習。有關詳細信息和示例章節,請參閱http://www.duntemann.com/assembly.html