我是靠谱客的博主 活泼水杯,最近开发中收集的这篇文章主要介绍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;
}

最后

以上就是活泼水杯为你收集整理的nasm 汇编输出 helloworld-windows 32位与64位测试通过的全部内容,希望文章能够帮你解决nasm 汇编输出 helloworld-windows 32位与64位测试通过所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(56)

评论列表共有 0 条评论

立即
投稿
返回
顶部