我是靠谱客的博主 儒雅唇膏,最近开发中收集的这篇文章主要介绍使用YASM编程 - 01,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

YASM 继承了NASM ,扩展了支持的语法和平台
支持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 SDKsWindowsv7.1ALib"
;
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

最后

以上就是儒雅唇膏为你收集整理的使用YASM编程 - 01的全部内容,希望文章能够帮你解决使用YASM编程 - 01所遇到的程序开发问题。

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

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

评论列表共有 0 条评论

立即
投稿
返回
顶部