一:背景

1. 简介

.NET 高级调试要想玩的好,看懂汇编是基本功,但看懂汇编和能写点汇编又完全是两回事,所以有时候看的多,总手痒痒想写一点,在 Windows 平台上搭建汇编环境不是那么容易,大多还是用微软的 MASM + DosBox 搭一个 8086 的环境,这玩意距今快 50 年了。

在以前想快捷的写一点汇编,借助的是 VC 编译器的 __asm 在 C/C++ 代码中内嵌一点,比如下面这样。


int main()
{
int num = 10; __asm {
mov[num], 20
} printf("num=%d", num);
}

便捷是便捷,但只能玩个局部,还是不够爽,所以本篇我们借助 nasm 来搭建一个 32bit 的汇编环境,当然 64bit 也是可以的, nasm 在 Linux 社区中非常有名。

二:搭建 x86 汇编环境

1. 前置基础构件

  1. nasm 下载

nasm 是一个非常有名的汇编器,官方网址:https://nasm.us/ 目前稳定版是 2.15.05

  1. gcc

大家都知道,源代码要变成可执行程序,步骤一般是: asm -> obj -> exe,前半部分由 nasm 负责,后半部分由 gcc 负责, gcc 是 Linux 上的刚需产品,在 Windows 上可以用 MinGW

下载网址:https://sourceforge.net/projects/mingw/files/MinGW

下载完之后,将下图中的 五项 全部勾选上进行安装。

bin, include,lib 全部配到环境变量的 PATH 中,然后打开控制台键入 gcc -v 看一下有没有配好。


PS C:\Users\Administrator\Desktop> gcc -v
Using built-in specs.
COLLECT_GCC=C:\MinGW\bin\gcc.exe
COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/mingw32/6.3.0/lto-wrapper.exe
Target: mingw32
Configured with: ../src/gcc-6.3.0/configure --build=x86_64-pc-linux-gnu --host=mingw32 --target=mingw32 --with-gmp=/mingw --with-mpfr --with-mpc=/mingw --with-isl=/mingw --prefix=/mingw --disable-win32-registry --with-arch=i586 --with-tune=generic --enable-languages=c,c++,objc,obj-c++,fortran,ada --with-pkgversion='MinGW.org GCC-6.3.0-1' --enable-static --enable-shared --enable-threads --with-dwarf2 --disable-sjlj-exceptions --enable-version-specific-runtime-libs --with-libiconv-prefix=/mingw --with-libintl-prefix=/mingw --enable-libstdcxx-debug --enable-libgomp --disable-libvtv --enable-nls
Thread model: win32
gcc version 6.3.0 (MinGW.org GCC-6.3.0-1)
PS C:\Users\Administrator\Desktop>
  1. vscode 插件

这里我准备用 vscode 来写汇编代码,主要安装两个插件。

  • The Netwide Assembler (NASM)

这个 nasm 官方提供的 语法高亮 插件。

  • GDB Debug

gdb 已经内嵌到了 gcc 中,方便于 code 调试。

2. vscode 自动化构建

玩过 vscode 的朋友应该知道,自动化构建需要自己写 tasks.json,这里我简单写了一个。


{
"version": "2.0.0",
"tasks": [
{
"label": "win86",
"type": "shell",
"command": "nasm.exe -f win32 -g -F cv8 -l app.lst app.asm; gcc app.obj -o app.exe",
"problemMatcher": {
"pattern": {
"regexp": "error"
}
},
"group": "build",
"presentation": {
"focus": true,
"panel": "dedicated",
"reveal": "silent",
"clear": true
}
}
]
}

然后就是配置启动 launch.json,代码如下:


{
"version": "0.2.0",
"configurations": [
{
"type": "gdb",
"request": "launch",
"name": "GDB32",
"program": "${workspaceFolder}/app.exe",
"stopOnEntry": true,
"preLaunchTask": "win86"
},
{
"type": "gdb",
"request": "launch",
"name": "GDB64",
"program": "${workspaceFolder}/app.exe",
"stopOnEntry": true,
"preLaunchTask": "win64"
}
]
}

到这里基础设施就全部搭建完成了,然后就是写一个简单的汇编程序,实现三个 printf 的打印,代码如下:


extern _printf
SECTION .data msg db 'Hello World!', 0Ah , 0h; num1 dd 100;
num1_int_fmt db 'num1=%d', 0Ah, 0h; num2 dq 3.14;
num2_flt_fmt db 'num2=%lf', 0Ah, 0h; SECTION .text global _main _main: push ebp
mov ebp , esp ; printf("Hello World\n");
mov eax , msg
push eax
call _printf
add esp, 4 ; printf("num1=%d",num1)
mov eax , [num1]
push eax
mov ebx , num1_int_fmt
push ebx ,
call _printf
add esp , 4 ; printf("num2=%lf",num2)
movq xmm0 , [num2]
sub esp , 0x8
movsd [esp] , xmm0
mov ebx , num2_flt_fmt
push ebx
call _printf
add esp , 0xc mov esp , ebp
pop ebp ret

输出结果如下:

从上面的代码看,我需要自己协调栈平衡,自己去管理寄存器和内存的使用,真的是太爽了。

二:总结

汇编看多了,总想自己动手试试,如果你也有这种想法,可以搭建一下玩玩,有一点遗憾的是,在 windows 中用 gdb 单步调试汇编目前还没搞定,在 linux 上很轻松,不过也不影响自己学习研究,毕竟可以用强大的 windbg 和 ollydbg 来实现单步调试,对吧!

最新文章

  1. 我对Jenkins的认识
  2. 类型引起的bug
  3. 设计一个简单的,低耗的能够区分红酒和白酒的感知器(sensor)
  4. oracle 获取系统时间(转)
  5. 立贴读 《CLR》
  6. vs2012快速将项目托管到github
  7. 【从零开始搭建自己的.NET Core Api框架】(七)授权认证进阶篇
  8. Centos 7 LVM xfs文件系统修复
  9. 【vue】饿了么项目的相关笔记链接
  10. HZNU ACM一日游 2019.3.17 【2,4,6-三硝基甲苯(TNT)】
  11. 20165221 JAVA第五周学习心得
  12. Android笔记--LinearLayout
  13. 数据库设计和ER模型-------之ER模型的基本概念(第二章)
  14. windows10下找回照片查看器的方法(仅作记录)
  15. 一次查找Windows Live Writer的VSPaste插件丢失RTF格式信息的经历
  16. Linux下安装和卸载jdk步骤详述
  17. 小结:线段树 & 主席树 & 树状数组
  18. tornado调用ioloop TracebackFuture实现非堵塞的模块
  19. maven项目将web2.5改为web3.1
  20. MongoDB 学习笔记四 C#调用MongoDB

热门文章

  1. vue3 vite2 封装 SVG 图标组件 - 基于 vite 创建 vue3 全家桶项目续篇
  2. python中的多线程与多进程
  3. IPv4 与 IPv6的区别
  4. Mapper 实体转换Entiy to Dto
  5. 20220728 - DP训练 #1
  6. paddle&蜜度 文本智能较对大赛经验分享(17/685)
  7. laravel 浏览器谷歌network返回报错html
  8. 一篇文章带你了解服务器操作系统——Linux简单入门
  9. 驱动开发:内核层InlineHook挂钩函数
  10. 1.nginx学习