nasm 汇编输出 helloworld-windows 32位与64位测试通过

使用nasm汇编,然后用visual studio的link连接成exe
选安装nasm与visual studio

// hello.asm
STD_OUTPUT_HANDLE   equ -11
NULL                equ 0

global GobleyGook
extern _ExitProcess@4, _GetStdHandle@4, _WriteConsoleA@20

section .data
msg                 db "Hello World!", 13, 10, 0
msg.len             equ $ - msg

section .bss
dummy               resd 1

section .text
GobleyGook:
    push    STD_OUTPUT_HANDLE
    call    _GetStdHandle@4

    push    NULL
    push    dummy
    push    msg.len
    push    msg
    push    eax
    call    _WriteConsoleA@20 

    push    NULL
    call    _ExitProcess@4
打开x86本机命令提示符
编译
nasm -f win32 hello.asm -o hello.obj
连接
link /subsystem:console /nodefaultlib /entry:GobleyGook hello.obj kernel32.lib
运行
hello.exe

【汇编说明】
hello.asm中的
extern是声明调用的函数,函数名在kernel32.lib库中
call前面的几个push是把call 这个函数需要的参数入栈,第一个push的是函数参数列表的最后一个,倒序
/entry:GobleyGook 是指定入口地址
_GetStdHandle@4是获取std句柄,也就是命令提示符句柄,返回的结果在eax寄存器,所以_WriteConsoleA@20的第一个参数就是最后一个push eax

打开  x64本机命令提示符  或者  x86本机命令提示符
导出 kernel32.lib 中的符号,也就是函数名 到文件

dumpbin /EXPORTS kernel32.lib >kernel32.txt

虽然都叫 kernel32.lib,但在x86与x64下不是同一个文件,所以 符号 (函数名称) 不同,链接会报找不到符号
导出的文件内有kernel32.lib的路径,是编译时使用的库文件

x86本机命令提示符, 运行时使用的是 system32 目录下
x64本机命令提示符, 运行时使用的是 syswow64 目录下

以下是的64位

// hello.asm  64位
STD_OUTPUT_HANDLE   equ -11
NULL                equ 0

global GobleyGook
extern ExitProcess, GetStdHandle, WriteConsoleA

section .data
msg                 db "Hello World!", 13, 10, 0
msg.len             equ $ - msg

section .bss
dummy               resq 1

section .text
GobleyGook:

    mov     ecx,0fffffff5h
    call    GetStdHandle

    mov     r9,dummy
    mov     r8d,0dh
    mov     rdx,msg
    mov     rcx,rax
    call    WriteConsoleA

    push    NULL
    call    ExitProcess
打开x64本机命令提示符
nasm -f win64 hello.asm -o hello.obj
link /subsystem:console /nodefaultlib /entry:GobleyGook /machine:X64 hello.obj kernel32.lib
hello.exe

【64位汇编说明】
64位函数调用没有用push,因为1.push不能直接64位, 2.push不能调用成功
windows的参数传递 (Parameter Passing, 函数参数列表从左到右,rcx,rdx,r8,r9的寄存器顺序)
GetStdHandle函数的结果在rax寄存器, mov rcx,rax就是把结果放入rcx作为WriteConsoleA的第一个参数

上面的64汇编是看的vs的反汇编代码所启发,f9加断点,f5运行到断点后,右键–转到反汇编

#include <Windows.h>

using namespace std;

int main()
{
	char* str = "Hello World!";
	DWORD byteswritten;

	HANDLE hwnd;
	hwnd = GetStdHandle(STD_OUTPUT_HANDLE);

	WriteConsole(hwnd, "Hello World!", 13, &byteswritten, NULL);  //断点行
	return 0;
}
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值