使用YASM编程 - 01
2017-09-01 18:12
253 查看
YASM 继承了NASM ,扩展了支持的语法和平台
支持INTEL 格式语法和 GNU AS 语法
下面是一个例子,实现了简单的invoke 调用和编程的一个基本的框架
它能够:
0 win32 程序,控制台打印
1 调用外部程序
2 被外部调用(入口函数)
3 数据段
4 代码段
5 函数定义
6 函数从栈传入参数,从eax返回值
7 include 其他的文件
8 编译
9 链接
支持INTEL 格式语法和 GNU AS 语法
下面是一个例子,实现了简单的invoke 调用和编程的一个基本的框架
它能够:
0 win32 程序,控制台打印
1 调用外部程序
2 被外部调用(入口函数)
3 数据段
4 代码段
5 函数定义
6 函数从栈传入参数,从eax返回值
7 include 其他的文件
8 编译
9 链接
;;;;;;;;;;;;;;;;;;;;;;;; ;windows.inc ;;;;;;;;;;;;;;;;;;;;;;;; %ifndef windows_inc %define windows_inc 1 extern _CreateFileA@28 extern _CreateFileW@28 extern _MessageBoxA@16 extern _MessageBoxW@16 extern _OutputDebugStringA@4 extern _OutputDebugStringW@4 extern _ExitProcess@4 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;帮助我们像使用C语言一样使用API ;定义很多宏供用户使用 %define CreateFileA _CreateFileA@28 %define CreateFileW _CreateFileW@28 %define MessageBoxA _MessageBoxA@16 %define MessageBoxW _MessageBoxW@16 %define OutputDebugStringA _OutputDebugStringA@4 %define OutputDebugStringW _OutputDebugStringW@4 %define ExitProcess _ExitProcess@4 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; %endif ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;test.asm ;这个是 YASM 的样板程序,使用一下NASM的各个语法使以后变成可以参考这个程序 ;大体一个程序使用一下的功能 ; 入口:必须以 _ 开始,因为在link 的时候 link /entry:xxxx ,这个xxxx 是C的符号xxxx, ; 真实的是_xxxx ; 数据段: ; section .data ; 在masm中是 .data 没有section修饰 ; 代码段: ; section .text ; 在masm中是 .code ; 导出的符号: ; global xxxx ; 必须要导出入口,否则链接程序找不到这个入口函数 ; 引入的符号: ; extern xxxx ; 说明这个符号是外部的,在此不存在,只是一个占位符,在其他模块应该能够找到它 ; 伪操作符 ; db ; dw ; equ ; 宏定义 ; %define xxxx yyyyyy ; 和 C的宏样子类似 ; 调用约定: ; 这里没有调用约定,所以导入的符号的名称都比较原始 ; 比如:MessageBoxA 这个函数,在dll内部其实是_MessageBoxA@16(因为它有4个函数所以叫16) ; 调用的时候 stdcall 不需要处理栈平衡,因此在我们call了之后什么都没有处理 ; 调用C函数的时候如何处理呢? ; push hello ; call _printf ; add esp,4 ; 只能这样手动的维持栈平衡 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;test.asm ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;编译和链接 ;vsyasm -f win32 -o obj test.asm ;link /entry:start /subsystem:console /debug /machine:x86 /out:test.exe /release /verbose:lib ; /libpath:"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Lib" ; kernel32.lib user32.lib test.obj msvcrt.lib ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;数据段,不可变 ;SECTION .data 都可以 %include "windows.inc" SECTION .data HelloMsg: db "Hello",0 TitleString db "msg",0 Hello : db "Hello Yasm",0x0a,0 printFormat : db "retValue=%d",0x0a,0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;includelib--------------------------- extern _printf ;------------------------------------- ;压栈 ;%macro push_param 1-* ;*表示宏的参数个数没有上限 ; %rep %0 ;参数旋转,最后一个参数为1 ; %rotate -1 ;将 %1 参数入栈 ; push %1 ; %endrep ;%endmacro ;;;;;;;;;;;;;;;;;;;;;;;;;;; ;macro invoke ;使用宏来实现MASM 中的invoke ;当参数最高达到2的时候,后续的 ;参数全部编程%2 ;invoke 只能调用参数个数>1的函数 ;参数个数=0的函数请使用 call 来调用 ;;;;;;;;;;;;;;;;;;;;;;;;;;;; %macro invoke 2-* %define _j %1 %rep %0-1 %rotate -1 push dword %1 %endrep call _j %endmacro ;%macro invoke 2+ ; ;循环%0 表示宏的参数个数 ; push_param %2 ; call %1 ;%endmacro ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SECTION .text global _start printRetValue: push ebp mov ebp,esp mov eax,[ebp+8] invoke _printf,printFormat,eax add esp,8 pop ebp ret add1: push ebp mov ebp,esp mov eax,[ebp+8] mov edx,[esp+0ch] add eax,edx pop ebp ret sayHello: mov eax,Hello push eax call _printf add esp,4 ret _start: invoke add1,100,200 invoke printRetValue,eax call sayHello invoke MessageBoxA,0,HelloMsg,TitleString,0 push HelloMsg call OutputDebugStringA invoke ExitProcess,0 ret
相关文章推荐
- Java基础知识强化之网络编程笔记01:InetAddress类的概述和使用
- 使用YASM编程 - 03
- 使用YASM编程 -07 模拟导入表
- 使用YASM编程 - 02
- 01.JAVA并发编程-线程的使用-基本概念
- 【Python 01】使用UE配置Python编程环境
- 使用YASM编程 - 05
- SpringMVC_01 SpringMVC五大组件、SpringMVC编程步骤(不使用注解进行配置)、SpringMVC编程步骤(利用注解进行配置)、参数获取、响应数据
- 使用YASM编程 - 04
- 01-编程工具-CMake使用教程
- 使用YASM编程 - 06
- 网络编程Socket之wireshark使用
- 体验 Java 9 交互式编程环境Jshell使用示例
- 【20090312-01】ArrayList的使用方法【转载】
- 3.Spark SQL:使用反射方式、编程方式,将RDD转换为DataFrame
- 第5周实验:GUI编程及JDK API的使用
- 4.Spark SQL:数据源Parquet之使用编程方式加载数据
- Python多线程编程使用Queue模块保持线程同步
- 多线程编程:何时使用同步类
- 转帖多线程编程使用互斥锁同步线程