我是接近使用汇编代码编程的硬件新手。所以我读了一本关于它的书,并找到了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
汇编程序组装它没有问题并且没有错误,但程序立即崩溃。我读到了不同的汇编语言,但关键是汇编代码因不同的编译器而不同,操作系统不同,所以我的错误在哪里?
答案 0 :(得分:3)
您要显示的代码是x86_32 linux代码
你可以说,因为它使用了Windows没有的int
次调用,而且这行:
nasm -f elf64 helloworld.asm
以ELF格式生成输出,这是一个linux可执行文件 Windows使用PE (可移植可执行文件),它是EEE的MS COFF变体。
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 :(得分:1)
以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 win32 -o executable.o executable.asm
ld -o executable.exe executable.o