64位Windows

时间:2018-04-20 18:44:25

标签: windows assembly x86-64 system-calls interrupt

我在Windows 10上安装了Cygwin。我一直在使用Cygwin使用Cygwin安装的“gcc”和“nasm”来编译/汇编c和汇编程序。据我所知,nasm具有-f win64模式,因此它可以组装64位程序。现在,对于Windows上的x64汇编编程,似乎youtube缺少教程。 youtube上的大多数汇编编程教程都是针对x64 linux或x32 windows的,我需要能够在x64窗口上将字符串打印到控制台,而无需使用任何外部函数,如C的“printf”。

StackOverflow链接对我不起作用:

64-bit windows assembler

据我所知,nasm使用-f win64扩展支持64位窗口。此外,答案与如何在x64位窗口上的汇编中编写实际程序无关

How to write hello world in assembler under Windows?

所有给出代码的答案只提供过时的Windows版本(32位)的代码,除了一个。我试过64位的一个答案,但链接目标文件的命令给我一个错误,系统找不到指定的路径。

windows x64 assembler?

此网站不包含任何代码,这正是我所需要的。另外,我正在尝试在nasm中编写Hello World程序。

64 bit assembly, when to use smaller size registers

这个问题实际上包含了一个hello world程序的代码,但是当在windows 10(我的设备)上的cygwin下执行时,我遇到了分段错误。

Why does Windows64 use a different calling convention from all other OSes on x86-64?

我尝试使用objdump -d反汇编C Hello World程序,但这会调用printf,一个预建的C函数,我试图避免使用外部函数。

我已经尝试过其他外部函数(例如Messagebox),但它们会返回错误,因为某些东西无法识别这些函数。此外,我尽量不使用任何外部函数,只有syscall,sysenter或中断。

CODE:

尝试#1:

    section .data
    msg db "Hello, World!", 10, 0
    section .text
    mov rax, 1
    mov rdi, 1
    mov rsi, msg
    mov rdx, 14
    syscall
    mov rax, 60
    mov rdi, 0
    syscall

问题:正确组装和链接,但在运行时会引发分段错误。

尝试#2:

    section .text
    mov ah, 0eh
    mov al, '!', 0
    mov bh, 0
    mov bl, 0
    int 10h

问题:没有正确组装;说“test.asm:3:错误:操作码和操作数的无效组合”

尝试#3:

    section .text
    msg db 'test', 10, 0
    mov rdi, 1
    mov rsi, 1
    mov rdx, msg
    mov rcx, 5
    syscall
    mov rdi, 60
    mov rsi, 0
    syscall

问题:正确组装和链接,但在运行时会引发分段错误。

尝试#4:

    section .text
    mov ah, 0eh
    mov al, '!'
    mov bh, 0
    mov bl, 0
    int 10h

问题:正确组装和链接,但在运行时会引发分段错误。

我只需要一个在64位Windows 10上运行的hello world程序集的示例.32位程序在运行它时似乎会返回错误。如果在不使用外部函数的情况下无法将字符串打印到控制台,那么使用外部函数并在64位Windows 10上运行的程序示例将会很不错。

我听说Windows中的系统调用的地址与linux中的地址差别很大。

1 个答案:

答案 0 :(得分:3)

  

尝试#1:

     

尝试#2:

Windows内部使用中断或系统调用。但是,他们没有正式记录,他们可能会随时改变微软想要改变它们

只有少数.dll个文件直接使用系统调用说明;所有程序都直接或间接访问这些.dll文件。

某个序列(例如mov rax, 5syscall)可能具有含义"打印出文本"在Windows更新之前,Microsoft可能会将此序列的含义更改为"删除文件" Windows更新后。

要做到这一点,微软必须更换内核和正式"允许的.dll文件。使用syscall指令。

调用Windows操作系统功能的唯一方法是保证您的程序在下一次Windows更新后仍在工作,就是调用.dll文件中的函数 - 就像您一样在C程序中执行此操作。

示例(32位代码):

push 1
push msg
push 14
call _write
mov dword [esp], 0
call _exit