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)

包含头文件

1
include header.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

无参宏

1
AAA EQU 100

将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中需要先取消符号