汇编代码在Windows 8 x64上

我刚接触使用汇编代码编程的硬件。 所以我读了一本关于它的书,并find了NASM汇编程序的示例代码:

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 

汇编器没有任何问题来组装它,并没有提供任何错误,但是程序立即崩溃。 我读了不同的汇编语言,但关键是汇编代码因不同的编译器而异,而不是不同的操作系统,所以我的错误在哪里?

你显示的代码是x86_32 linux代码。
你可以告诉,因为它使用了Windows没有的int调用,而且这一行:

 nasm -f elf64 helloworld.asm 

以ELF格式生成输出,这是一个linux可执行文件。
Windows使用PE (便携式可执行文件) ,这是COFF的MS EEE变体。

x64代码使用RAXRBX ….,虽然32位变体寄存器EAX等也很重要。

在你学习如何编写程序集之前。
您需要知道ABI(调用约定)和系统的API。

对于ABI看看: 呼叫约定 – PDF

如果您想知道如何在Windows中进行API调用,请编写一个简单的C程序来完成这个工作,然后获得一个反汇编程序并查看x86代码。
有关API调用的更多信息,请参阅MSDN,特别是:

x64调用约定概述
Windows控制台功能
ExitProcess函数

以PE格式组装您的可执行文件,并将int 0x80更改为一个call ExecuteInterrupt128 。 你可以给它一个相同的名字。 您可以学习如何在NASM上编写PE可执行文件。 只要去堆栈溢出的主页。

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