2013-10-13 64 views
1

我剛剛接觸使用匯編代碼進行編程的硬件。所以,我讀了一本書,並發現了NASM彙編此示例代碼:Windows 8 x64上的彙編代碼

segment .text        ;code segment 
global main         ;must be declared for linker 
main:          ;tell linker entry point 
mov edx,len         ;message length 
mov ecx,msg         ;message to write 
mov ebx,1         ;file descriptor (stdout) 
mov eax,4         ;system call number (sys_write) 
int 0x80         ;call kernel 
mov eax,1         ;system call number (sys_exit) 
int 0x80         ;call kernel 

segment .data        ;data segment 
msg db 'Hello, world!',0xa     ;our dear string 
len equ $ - msg        ;length of our dear string 

所以我用下面的命令編譯它:

nasm -f elf64 helloworld.asm 
ld -s -o helloworld.exe helloworld.o 

彙編器有沒有問題,進行組裝,並給出沒有錯誤,但程序立即崩潰。我讀過不同的彙編語言,但問題是彙編代碼因不同的編譯器而異,而不是使用不同的操作系統,所以我的錯誤在哪裏?

+0

爲什麼你認爲這個問題是操作系統。如果運行Windows 7,它可能會在同一臺計算機上崩潰。您是否測試過這種情況?如果它不是操作系統,那就離開機器。 –

+0

對於任何x64操作系統,我會先嚐試'mov rcx,msg'(我也懷疑Win 8使用linux風格的系統調用,Windows 7沒有。) –

+5

[Win8似乎並沒有使用INT作爲系統調用](http ://wiki.osdev.org/SYSENTER)。 –

回答

3

您顯示的代碼是x86_32 linux代碼。
你可以告訴,因爲它使用int調用,Windows不和這條線:

nasm -f elf64 helloworld.asm 

ELF格式,這是一個Linux可執行生成輸出。
Windows使用PE (便攜式可執行文件),它是COFF的MS EEE變體。

x64代碼使用RAX,RBX ....,雖然32位變體寄存器EAX等也很重要。

在您可以學習如何編寫程序集之前。
您需要知道ABI(調用約定)和系統的API。

對於ABI看看:Calling Conventions - PDF

如果你想知道怎麼做的Windows API調用,寫一個簡單的C程序,沒有工作,然後讓反彙編,並期待在x86代碼。
有關API調用的詳細信息看看MSDN,具體如下:

Overview of x64 Calling Conventions
Windows Console functions
ExitProcess function

1

組裝您對PE格式的可執行和改變int 0x80call ExecuteInterrupt128。 你可以給它一個相同的名字。您可以學習如何在NASM上編寫PE可執行文件。 只需轉到Stack Overflow的主頁。

的ExecuteInterrupt128功能應該是這樣:

push ebp 
mov ebp, esp 
cmp eax, byte +1 
je SleepSystem 
cmp eax, byte +4 
je PrintString 
... 
SleepSystem: 
push byte -1 
call Sleep 
leave 
ret 
PrintString: 
push -11 
call GetStdHandle 
push byte +0 
push byte +6 
lea esi, [ebp-4] 
push edx 
push ecx 
push eax 
call WriteConsoleA 
leave 
ret 

或者試試這個命令:

nasm -f win32 -o executable.o executable.asm 
    ld -o executable.exe executable.o