Windows 8 x64上的程序集代码

Windows 8 x64上的程序集代码,windows,assembly,x86-64,nasm,Windows,Assembly,X86 64,Nasm,我不熟悉用汇编代码编程的硬件。所以我读了一本关于它的书,找到了NASM汇编程序的示例代码: segment .text ;code segment global main ;must be declared for linker main: ;tell linker entry point mov

我不熟悉用汇编代码编程的硬件。所以我读了一本关于它的书,找到了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
    nasm -f win32 -o executable.o executable.asm
    ld -o executable.exe executable.o

汇编程序组装它没有问题,也没有给出错误,但程序会立即崩溃。我读过不同的汇编语言,但重点是汇编代码因不同的编译器而不同,而不是因不同的操作系统而不同,所以我的错误在哪里?

您显示的代码是x86_32 linux代码。
您可以知道,因为它使用
int
调用Windows不使用的调用,这一行:

nasm -f elf64 helloworld.asm
以linux可执行文件的格式生成输出。
Windows使用PE(可移植可执行文件),它是的MS变体

x64代码使用
RAX
RBX
…,尽管32位变量寄存器
EAX
等也具有很强的功能

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

对于ABI,请查看:

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




显示的代码是x86_32 linux代码。
您可以知道,因为它使用
int
调用Windows不使用的调用,这一行:

nasm -f elf64 helloworld.asm
以linux可执行文件的格式生成输出。
Windows使用PE(可移植可执行文件),它是的MS变体

x64代码使用
RAX
RBX
…,尽管32位变量寄存器
EAX
等也具有很强的功能

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

对于ABI,请查看:

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




将可执行文件汇编为PE格式,并将
int 0x80
更改为
call 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 elf64 helloworld.asm
ld -s -o helloworld.exe helloworld.o
    nasm -f win32 -o executable.o executable.asm
    ld -o executable.exe executable.o

以PE格式组装可执行文件,并将
int0x80
更改为
调用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 elf64 helloworld.asm
ld -s -o helloworld.exe helloworld.o
    nasm -f win32 -o executable.o executable.asm
    ld -o executable.exe executable.o

为什么你认为问题出在操作系统上。如果运行Windows7,它可能会在同一台机器上崩溃。你测试过那个场景吗?如果不是操作系统,这就离开了机器。对于任何x64操作系统,我都会首先尝试
mov rcx,msg
(我也怀疑Win 8使用linux风格的系统调用。Windows 7没有)。在Windows上,您可以从system32.dll调用ExitProcess退出。系统调用非常特定于操作系统。您试图在Windows中执行Linux系统调用,这是行不通的。改用WinAPI函数,如
WriteConsole
ExitProcess
。为什么您认为问题出在操作系统上。如果运行Windows7,它可能会在同一台机器上崩溃。你测试过那个场景吗?如果不是操作系统,这就离开了机器。对于任何x64操作系统,我都会首先尝试
mov rcx,msg
(我也怀疑Win 8使用linux风格的系统调用。Windows 7没有)。在Windows上,您可以从system32.dll调用ExitProcess退出。系统调用非常特定于操作系统。您试图在Windows中执行Linux系统调用,这是行不通的。改用WinAPI函数,如
WriteConsole
ExitProcess