【问题标题】:Nasm x64 code for windowsWindows的Nasm x64代码
【发布时间】:2013-12-07 18:45:06
【问题描述】:

我在互联网上搜索了一个用于 Windows 的 NASM x64 示例,但我只找到了一个,而且,不起作用:(,刚刚找到用于 linux,代码有人可以展示如何创建 Hello world NASM 的示例x64 窗口

x64 assembly code for NASM linux

x64 Assembly code for NASM windows

【问题讨论】:

  • 如果您将这些“hello World”示例复制到问题中,而不是仅仅发布链接,将会很有帮助。我想这样的东西会很有用。
  • forum.nasm.us 有一些可能有用的 win64 示例。
  • 什么是“不工作”? (哪个错误消息/哪个行为/...)

标签: windows assembly x86-64 nasm


【解决方案1】:

一个谈论那个的话题:https://openclassrooms.com/forum/sujet/nasm-win64-bug-hello-world。 有人在 NASM [Win64] 中提出了一个解决方案。

main.asm

extern GetStdHandle
extern WriteFile
extern Sleep
extern ExitProcess
 
%define STD_OUTPUT_HANDLE (-11)
 
section .data
hello_str db "Hello World", 13, 10
hello_size equ ($ - hello_str)
 
output_handle dq 0
 
section .text
 
global main
main:
    ;Aligne la pile
    and rsp, 0xFFFF_FFFF_FFFF_FFF0
    mov rbp, rsp
 
    ;Récupère l'output standart
    mov ecx, STD_OUTPUT_HANDLE
    call GetStdHandle
    mov [output_handle], rax
     
    ;Affiche le message
    ;Shadow Space
    sub rsp, 48
    mov rcx, [output_handle]
    mov rdx, hello_str
    mov r8d, hello_size
    mov r9, 0
    mov QWORD [rsp + 32], 0
    call WriteFile
    ;Détruit l'espace de pile alloué pour les paramètres de la fonction
    add rsp, 48
     
    ;Pause de 1000 millisecondes pour donner le temps de voir
    ;Shadow Space
    sub rsp, 0x20
    mov ecx, 1000
    call Sleep
     
    ;Quitte
    xor rcx, rcx
    call ExitProcess

make.bat

@echo off
 
nasm.exe -fwin64 main.asm -o Obj/main.o
gpp.exe -s -m64 Obj/main.o -o hello.exe C:\Windows\System32\kernel32.dll
 
pause

“请注意,我使用 g++ 链接,但我认为您可以将其调整为您的链接器。”

【讨论】:

  • GetStdHandle 遵循与其他函数相同的调用约定;您应该在调用它之前 保留影子空间(以及以后需要的空间)。或者根本没有,因为你的main 没有返回(而是调用一个退出函数),只需让 main 自己的影子空间和返回地址被覆盖,就像你已经为 GetStdHandle 所做的那样。在函数期间不断调整 RSP 肯定是没有意义的,比如 add rsp, 48 / sub rsp, 0x20
  • 另外,您应该使用default rel,所以mov rcx, [output_handle] 将使用RIP 相对寻址模式(比32 位绝对[disp32] 更有效)。或者更好的是,只使用寄存器(或至少使用堆栈;您甚至将 RBP 设置为帧指针......),而不是静态存储。例如mov rcx, rax,如果文件句柄在 Windows 中确实是 64 位的。 (显然所有 Windows 句柄都是 32 位的:What is the range of a Windows HANDLE on a 64 bits application? 所以mov ecx, eax 将其零扩展为 RCX)
  • 让每个 Windows 程序都有自己的睡眠或等待输入是一种反模式。开发人员应该设置一个环境,在现有终端中运行命令,或者在手动关闭之前保持打开状态的新终端。或者使用 .bat 或其他东西来运行程序,然后暂停。
  • (我猜你只是复制了别人写的这段代码,但现在它在你的答案中,所以这是你对 Hello World 示例的推荐。)
猜你喜欢
  • 2013-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-14
  • 1970-01-01
  • 1970-01-01
  • 2022-10-04
相关资源
最近更新 更多