x16基本格式
1 2 3 4 5 6 7
| assume cs:code
code segment;指定段 int 21h;退出 code ends end
|
x86基本格式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| .586;指定指令集版本 .model flat,stdcall;设置内存模型和调用约定:_edecl,_stdcall,_fastcall,_thiscall option casemap:none;区分大小写
includelib ucrt.lib;导入c相关标准库 includelib legacy_stdio_definitions.lib;导入c相关库
includelib Kernel32.lib includelib User32.lib
MessageBoxA proto hwnd:DWORD,lpText:BYTE,lpCaption:BYTE,uType:DWORD ExitProcess proto uCode:DWORD
extern printf:proc;声明外部函数
.data;指定段 szFormat db '%d', 0
.code;指定段 main proc mov eax,64h push eax;函数调用 lea ecx,szFormat push ecx call printf add esp,8;c标准
push 0 push 0 push 0 push 0 call MessageBoxA; push 0 call ExitProcess;win标准 或者可以写invoke ExitProcess,0 main endp end
|
汇编头文件(.inc)
包含头文件
伪指令
invoke
使用前必须先定义,比如上面的ExitProcess proto uCode:DWORD
1
| invoke farproc,para1,para2,...
|
只能用于win32 api
Download The MASM32 SDK下载MASM32SDK
效果是可以直接导入已经定义好的函数,可以直接invoke
在项目属性中Microsoft Macro Assembler-include Paths中附加MASM中的include目录,然后可以直接这样使用函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| .586;指定指令集版本 .model flat,stdcall;设置内存模型和调用约定:_edecl,_stdcall,_fastcall,_thiscall option casemap:none;区分大小写
includelib ucrt.lib;导入c相关标准库 includelib legacy_stdio_definitions.lib;导入c相关库
include Kernel32.inc include User32.inc
includelib Kernel32.lib includelib User32.lib
extern printf:proc;声明外部函数
.data;指定段 szFormat db '%d', 0
.code main proc mov eax,64h push eax;函数调用 lea ecx,szFormat push ecx call printf add esp,8;c标准
push 0 push 0 push 0 push 0 call MessageBoxA; push 0 call ExitProcess;win标准 或者可以写invoke ExitProcess,0 main endp
end
|
对于自己定义的函数,使用
1 2 3 4 5 6
| addx proc numA:dword,numB:dword xor eax,eax add eax,numA add eax,numB ret addx endp
|
这样的格式,也可以用invoke调用,对于C库的cstd函数,可以通过这个方式进行一次std的封装。
if
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| main proc mov dwIndex,11 .if dwIndex== 10 mov dwNumber,10 invoke printNumber,dwNumber .elseif deIndex >= 12 mov dwNumber,12 invoke printNumber,dwNumber .else mov dwNumber,0 invoke printNumber,dwNumber .endif main endp end
.break;跳出循环 .continue;跳到条件检查
|
while
1 2 3 4
| mov dwIndex,100 .while dwIndex>0 dec deIndex .endw
|
宏
无参宏
将AAA当100
有参宏
1 2 3 4 5 6 7 8 9 10 11 12
| ;定义 MyAdd MACRO n1 add eax,n1 endm ;使用 MyAdd <1>;简单参数也可以直接MyAdd 1
MyAdd2 MACRO reg,n1 add reg,n1 endm
MyAdd eax,10
|
结构体
在data段外声明
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| Point struct;声明 x word ? y word ? Point ends
.data MyPoint Point<?>;不初始化定义
.code main proc mov MyPoint.x,123 mov MyPoint.y,456 main endp end
|
内联汇编
vs中可以在c和cpp中使用内联汇编
x86:
1 2 3 4 5
| _asm{ push MB_OK;可以直接传宏 call myFunc;可以直接调用定义的函数 _emit 1;立即数 }
|
x64:
在生成依赖项中勾选masm,新建asm文件
1 2 3 4 5 6 7
| .code Myadd proc mov ecx,edx mov eax,ecx ret Myadd endp end
|
再声明head.h
1
| exten "C" DWORD Myadd(DWORD a,DWORD b);
|
包含这个文件即可直接使用
x64基本格式
1 2 3 4 5 6 7
| .code main proc sub rsp,28h add rsp,28h ret main endp end
|
可以直接写代码,调用函数用fastcall
1 2 3
| .data .data?;定义未初始化数据 .const;定义常量
|
通过修改编译器为inter,可以继续使用内联汇编
可以直接使用vs或者ida查看c/cpp代码然后取得相应的汇编代码,避免麻烦
VS中需要先取消符号