Destination | Constant size |
RAX | 32 |
EAX | 32 |
AX | 16 |
AL | 8 |
AH | 8 |
mem32 | 32 |
mem64 | 32 |
call
ret
dword
or sdword
qword
not
neg
jmp
lea
.data
section can hold initialized data values; the .data?
section can contain only uninitialized variables..code
and .const
.data
and .data?
.data
) label
some_type to inform MASM that the following data is of type some_type when, in fact, it could be another type.align 8
statement.b
is at an address that is at the last byte in an MMU page and the next page is not readable, loading a word from the memory location starting with b
will produce a general protection fault.xchg al, ah
or xchg ah, al
bswap eax
bswap rax
[RSP ±
const]
addressing mode.imul
reg,
constantimul
destreg,
srcreg,
constantimul
destreg,
srcreg=
, equ
, textequ
<
and >
around the string literal; for example, <"a long string">
.lengthof
this
and $
$-startingLocation
.val1 = 0
val2 = val1 + 1
val3 = val2 + 1
etc.
typedef
directiveqword
data declaration, or another data type that is 64 bits in sizeoffset
operatorarray byte 10 dup (?)
(as an example)dup
operator operand; for example, 5 dup (2, 3)
. +
index * 4
(4 is the element size), (b) W[i,j] =
base_address + (i * 8 + j) * 2
(2 is the element size), (c) R[i,j,k] =
base_address +(((i * 4) + j) * 6 + k) * 8
(8 is the element size)W word 4 dup (8 dup (?))
struct
and ends
union
and ends
id::
.option noscoped
directive just before the procedure.push
instruction to save the register values on the stack upon entry into the procedure; then use the pop
instruction to restore the register values immediately before returning from the procedure.push rbp
mov rbp, rsp
sub rsp, sizeOfLocals ; Assuming there are local variables
leave
ret
and rsp, -16
textequ
directives or the MASM local directivevar1
: –2; local2
: –8 (MASM aligns variable on dword boundary); dVar
: –9; qArray
: –32 (base address of array is the lowest memory address); rlocal
: –40 (base address of array is the lowest memory address); ptrVar
: –48option prologue:PrologueDef
and option epilogue:EpilogueDef
. Should also supply option prologue:none
and option epilogue:none
to turn this off.ret
instruction appearsparm1
: RBP + 16; parm2
: RBP + 24; parm3
: RBP + 32; parm4
: RBP + 40mov rax, parm4
mov al, [rax]
lclVar1
: RBP – 1; lclVar2
: RBP – 4 (aligned to 2-byte boundary); lclVar3
: RBP – 8; lclVar4
: RBP – 16call
parm instruction, where parm is the procedural parameter, a qword variable containing the address of the procedure. You could also load the parameter value into a 64-bit register and indirectly call the procedure through that register.mul
operation: 16 bits; 16-bit mul
operation: 32 bits; 32-bit mul
operation: 64 bits; 64-bit mul
operator: 128 bits. The CPU put the products at AX for 8×8 products, DX:AX for 16×16 products, EDX:EAX for 32×32 products, and RDX:RAX for 64×64 products.imul
instruction produces a 2 × n-bit result, uses implied operands (AL, AX, EAX, and RAX), and modifies the AH, DX, EDX, and RDX registers. Also, the extended-precision imul
instruction does not allow constant operands, whereas the generic imul
instruction does.cbw
, cwd
, cdq
, and cqo
test
instruction is the same as the and
instruction except it does not store the result to the destination (first) operand; it only sets the flags.x = x + y
mov eax, x
add eax, y
mov x, eax
x = y – z
mov eax, y
sub eax, z
mov x, eax
x = y * z
mov eax, y
imul eax, z
mov x, eax
x = y + z * t
mov eax, z
imul eax, t
add eax, y
mov x, eax
x = (y + z) * t
mov eax, y
add eax, z
imul eax, t
mov x, eax
x = -((x*y)/z)
mov eax, x
imul y ; Note: Sign-extends into EDX
idiv z
mov x, eax
x = (y == z) && (t != 0)
mov eax, y
cmp eax, z
sete bl
cmp t, 0
setne bh
and bl, bh
movzx eax, bl ; Because x is a 32-bit integer
mov x, eax
x = x * 2
shl x, 1
x = y * 5
mov eax, y
lea eax, [eax][eax*4]
mov x, eax
Here is another solution:
mov eax, y
mov ebx, eax
shl eax, 2
add eax, ebx
mov x, eax
x = y * 8
mov eax, y
shl eax, 3
mov x, eax
x = x /2
shr x, 1
x = y / 8
mov ax, y
shr ax, 3
mov x, ax
x = z / 10
movzx eax, z
imul eax, 6554 ; Or 6553
shr eax, 16
mov x, ax
x = x + y
fld x
fld y
faddp
fstp x
x = y – z
fld y
fld z
fsubp
fstp x
x = y * z
fld y
fld z
fmulp
fstp x
x = y + z * t
fld y
fld z
fld t
fmulp
faddp
fstp x
x = (y + z) * t
fld y
fld z
faddp
fld t
fmulp
fstp x
x = -((x * y)/z)
fld x
fld y
fmulp
fld z
fdivp
fchs
fstp x
x = x + y
movss xmm0, x
addss xmm0, y
movss x, xmm0
x = y – z
movss xmm0, y
subss xmm0, z
movss x, xmm0
x = y * z
movss xmm0, y
mulss xmm0, z
movss x, xmm0
x = y + z * t
movss xmm0, z
mulss xmm0, t
addss xmm0, y
movss x, xmm0
b = x < y
fld y
fld x
fcomip st(0), st(1)
setb b
fstp st(0)
b = x >= y && x < z
fld y
fld x
fcomip st(0), st(1)
setae bl
fstp st(0)
fld z
fld x
fcomip st(0), st(1)
setb bh
fstp st(0)
and bl, bh
mov b, bl
lea
instruction or the offset
operator.option noscoped
option scoped
jmp
reg64 and jmp
mem64jpo
and jpe
cmov
cc
reg,
src, where cc is one of the conditional suffixes (which follow a conditional jump), reg is a 16-, 32-, or 64-bit register, and src is a source register or memory location that is the same size as reg.if(x == y || z > t)
{
Do something
}
mov eax, x
cmp eax, y
sete bl
mov eax, z
cmp eax, t
seta bh
or bl, bh
jz skipIF
Code for statements that "do something"
skipIF:
if(x != y && z < t)
{
THEN statements
}
Else
{
ELSE statements
}
mov eax, x
cmp eax, y
setne bl
mov eax, z
cmp eax, t
setb bh
and bl, bh
jz doElse
Code for THEN statements
jmp endOfIF
doElse:
Code for ELSE statements
endOfIF:
1st IF:
mov ax, x
cmp ax, y
jeq doBlock
mov eax, z
cmp eax, t
jnl skipIF
doBlock: Code for statements that "do something"
skipIF:
2nd IF:
mov eax, x
cmp eax, y
je doElse
mov eax, z
cmp eax, t
jnl doElse
Code for THEN statements
jmp endOfIF
doElse:
Code for ELSE statements
endOfIF:
switch(s)
{
case 0: case 0 code break;
case 1: case 1 code break;
case 2: case 2 code break;
case 3: case 3 code break;
}
mov eax, s ; Zero-extends!
cmp eax, 3
ja skipSwitch
lea rbx, jmpTbl
jmp [rbx][rax * 8]
jmpTbl qword case0, case1, case2, case3
case0: case 0 code
jmp skipSwitch
case1: case 1 code
jmp skipSwitch
case2: case 2 code
jmp skipSwitch
case3: case 3 code
skipSwitch:
switch(t)
{
case 2: case 0 code break;
case 4: case 4 code break;
case 5: case 5 code break;
case 6: case 6 code break;
default: default code
}
mov eax, t ; Zero-extends!
cmp eax, 2
jb swDefault
cmp eax, 6
ja swDefault
lea rbx, jmpTbl
jmp [rbx][rax * 8 – 2 * 8]
jmpTbl qword case2, swDefault, case4, case5, case6
swDefault: default code
jmp endSwitch
case2: case 2 code
jmp endSwitch
case4: case 4 code
jmp endSwitch
case5: case 5 code
jmp endSwitch
case6: case 6 code
endSwitch:
switch(u)
{
case 10: case 10 code break;
case 11: case 11 code break;
case 12: case 12 code break;
case 25: case 25 code break;
case 26: case 26 code break;
case 27: case 27 code break;
default: default code
}
lea rbx, jmpTbl1 ; Assume cases 10-12
mov eax, u ; Zero-extends!
cmp eax, 10
jb swDefault
cmp eax, 12
jbe sw1
cmp eax, 25
jb swDefault
cmp eax, 27
ja swDefault
lea rbx, jmpTbl2
jmp [rbx][rax * 8 – 25 * 8]
sw1: jmp [rbx][rax*8-2*8]
jmpTbl1 qword case10, case11, case12
jmpTbl2 qword case25, case26, case27
swDefault: default code
jmp endSwitch
case10: case 10 code
jmp endSwitch
case11: case 11 code
jmp endSwitch
case12: case 12 code
jmp endSwitch
case25: case 25 code
jmp endSwitch
case26: case 26 code
jmp endSwitch
case27: case 27 code
endSwitch:
while(i < j)
{
Code for loop body
}
whlLp:
mov eax, i
cmp eax, j
jnl endWhl
Code for loop body
jmp whlLp
endWhl:
while(i < j && k != 0)
{
Code for loop body, part a
if(m == 5) continue;
Code for loop body, part b
if(n < 6) break;
Code for loop body, part c
}
; Assume short-circuit evaluation:
whlLp:
mov eax, i
cmp eax, j
jnl endWhl
mov eax, k
cmp eax, 0
je endWhl
Code for loop body, part a
cmp m, 5
je whlLp
Code for loop body, part b
cmp n, 6
jl endWhl
Code for loop body, part c
jmp whlLp
endWhl:
do
{
Code for loop body
} while(i != j);
doLp:
Code for loop body
mov eax, i
cmp eax, j
jne doLp
do
{
Code for loop body, part a
if(m != 5) continue;
Code for loop body, part b
if(n == 6) break;
Code for loop body, part c
} while(i < j && k > j);
doLp:
Code for loop body, part a
cmp m, 5
jne doCont
Code for loop body, part b
cmp n, 6
je doExit
Code for loop body, part c
doCont: mov eax, i
cmp eax, j
jnl doExit
mov eax, k
cmp eax, j
jg doLp
doExit:
for(int i = 0; i < 10; ++i)
{
Code for loop body
}
mov i, 0
forLp: cmp i, 10
jnl forDone
Code for loop body
inc i
jmp forLp
forDone:
mov rax, qword ptr y
add rax, qword ptr z
mov qword ptr x, rax
mov rax, qword ptr y[8]
adc rax, qword ptr z[8]
mov qword ptr x[8], rax
mov rax, qword ptr y
add rax, qword ptr z
mov qword ptr x, rax
mov eax, dword ptr z[8]
adc eax, qword ptr y[8]
mov dword ptr x[8], eax
mov eax, dword ptr y
add eax, dword ptr z
mov dword ptr x, eax
mov ax, word ptr z[4]
adc ax, word ptr y[4]
mov word ptr x[4], ax
mov rax, qword ptr y
sub rax, qword ptr z
mov qword ptr x, rax
mov rax, qword ptr y[8]
sbb rax, qword ptr z[8]
mov qword ptr x[8], rax
mov rax, qword ptr y[16]
sbb rax, qword ptr z[16]
mov qword ptr x[16], rax
mov rax, qword ptr y
sub rax, qword ptr z
mov qword ptr x, rax
mov eax, dword ptr y[8]
sbb eax, dword ptr z[8]
mov dword ptr x[8], eax
mov rax, qword ptr y
mul qword ptr z
mov qword ptr x, rax
mov rbx, rdx
mov rax, qword ptr y
mul qword ptr z[8]
add rax, rbx
adc rdx, 0
mov qword ptr x[8], rax
mov rbx, rdx
mov rax, qword ptr y[8]
mul qword ptr z
add x[8], rax
adc rbx, rdx
mov rax, qword ptr y[8]
mul qword ptr z[8]
add rax, rbx
mov qword ptr x[16], rax
adc rdx, 0
mov qword ptr x[24], rdx
mov rax, qword ptr y[8]
cqo
idiv qword ptr z
mov qword ptr x[8], rax
mov rax, qword ptr y
idiv qword ptr z
mov qword ptr x, rax
; Note: order of comparison (HO vs. LO) is irrelevant
; for "==" comparison.
mov rax, qword ptr x[8]
cmp rax, qword ptr y[8]
jne skipElse
mov rax, qword ptr x
cmp rax, qword ptr y
jne skipElse
then code
skipElse:
mov rax, qword ptr x[8]
cmp rax, qword ptr y[8]
jnb skipElse
mov rax, qword ptr x
cmp rax, qword ptr y
jnb skipElse
then code
skipElse:
mov rax, qword ptr x[8]
cmp rax, qword ptr y[8]
jna skipElse
mov rax, qword ptr x
cmp rax, qword ptr y
jna skipElse
then code
skipElse:
; Note: order of comparison (HO vs. LO) is irrelevant
; for "!=" comparison.
mov rax, qword ptr x[8]
cmp rax, qword ptr y[8]
jne doElse
mov rax, qword ptr x
cmp rax, qword ptr y
je skipElse
doElse:
then code
skipElse:
; Note: order of comparison (HO vs. LO) is irrelevant
; for "==" comparison.
mov eax, dword ptr x[8]
cmp eax, dword ptr y[8]
jne skipElse
mov rax, qword ptr x
cmp rax, qword ptr y
jne skipElse
then code
skipElse:
mov eax, dword ptr x[8]
cmp eax, dword ptr y[8]
jnb skipElse
mov rax, qword ptr x
cmp rax, qword ptr y
jnb skipElse
then code
skipElse:
mov eax, dword ptr x[8]
cmp eax, dword ptr y[8]
jna skipElse
mov rax, qword ptr x
cmp rax, qword ptr y
jna skipElse
then code
skipElse:
neg qword ptr x[8]
neg qword ptr x
sbb qword ptr x[8], 0
xor rax, rax
xor rdx, rdx
sub rax, qword ptr x
sbb rdx, qword ptr x[8]
mov qword ptr x, rax
mov qword ptr x[8], rdx
mov rax, qword ptr y
mov rdx, qword ptr y[8]
neg rdx
neg rax
sbb rdx, 0
mov qword ptr x, rax
mov qword ptr x[8], rdx
xor rdx, rdx
xor rax, rax
sub rax, qword ptr y
sbb rdx, qword ptr y[8]
mov qword ptr x, rax
mov qword ptr x[8], rdx
mov rax, qword ptr y
and rax, qword ptr z
mov qword ptr x, rax
mov rax, qword ptr y[8]
and rax, qword ptr z[8]
mov qword ptr x[8], rax
mov rax, qword ptr y
or rax, qword ptr z
mov qword ptr x, rax
mov rax, qword ptr y[8]
or rax, qword ptr z[8]
mov qword ptr x[8], rax
mov rax, qword ptr y
xor rax, qword ptr z
mov qword ptr x, rax
mov rax, qword ptr y[8]
xor rax, qword ptr z[8]
mov qword ptr x[8], rax
mov rax, qword ptr y
not rax
mov qword ptr x, rax
mov rax, qword ptr y[8]
not rax
mov qword ptr x[8], rax
mov rax, qword ptr y
shl rax, 1
mov qword ptr x, rax
mov rax, qword ptr y[8]
rcl rax, 1
mov qword ptr x[8], rax
mov rax, qword ptr y[8]
shr rax, 1
mov qword ptr x[8], rax
mov rax, qword ptr y
rcr rax, 1
mov qword ptr x rax
mov rax, qword ptr y[8]
sar rax, 1
mov qword ptr x[8], rax
mov rax, qword ptr y
rcr rax, 1
mov qword ptr x, rax
rcl qword ptr x, 1
rcl qword ptr x[8], 1
rcr qword ptr x[8], 1
rcr qword ptr x, 1
btoh proc
mov ah, al ; Do HO nibble first
shr ah, 4 ; Move HO nibble to LO
or ah, '0' ; Convert to char
cmp ah, '9' + 1 ; Is it "A" to "F"?
jb AHisGood
; Convert 3Ah to 3Fh to "A" to "F".
add ah, 7
; Process the LO nibble here.
AHisGood: and al, 0Fh ; Strip away HO nibble
or al, '0' ; Convert to char
cmp al, '9' + 1 ; Is it "A" to "F"?
jb ALisGood
; Convert 3Ah to 3Fh to "A" to "F".
add al, 7
ALisGood: ret
btoh endp
qToStr
twice: once with the HO 64 bits and once with the LO 64 bits. Then concatenate the two strings.fbstp
-
) character and negate the value; then call the unsigned decimal conversion function. If the number is 0 or positive, just call the unsigned decimal conversion function.; Inputs:
; RAX - Number to convert to string.
; CL - minDigits (minimum print positions).
; CH - Padding character.
; RDI - Buffer pointer for output string.
minDigits
parameter specifies the minimum string size.; On Entry:
; r10 - Real10 value to convert.
; Passed in ST(0).
; fWidth - Field width for the number (note that this
; is an *exact* field width, not a minimum
; field width).
; Passed in EAX (RAX).
; decimalpts - # of digits to display after the decimal pt.
; Passed in EDX (RDX).
; fill - Padding character if the number is smaller
; than the specified field width.
; Passed in CL (RCX).
; buffer - r10ToStr stores the resulting characters
; in this string.
; Address passed in RDI.
; maxLength - Maximum string length.
; Passed in R8D (R8).
fWidth
#
characters.; On Entry:
; e10 - Real10 value to convert.
; Passed in ST(0).
; width - Field width for the number (note that this
; is an *exact* field width, not a minimum
; field width).
; Passed in RAX (LO 32 bits).
; fill - Padding character if the number is smaller
; than the specified field width.
; Passed in RCX.
; buffer - e10ToStr stores the resulting characters in
; this buffer (passed in EDI).
; Passed in RDI (LO 32 bits).
; expDigs - Number of exponent digits (2 for real4,
; 3 for real8, and 4 for real10).
; Passed in RDX (LO 8 bits).
lea rbx, f
mov al, input
xlat
lea rbx, f
movzx rax, input
mov ax, [rbx][rax * 2]
lea rbx, f
movzx rax, input
mov al, [rbx][rax * 1]
lea rbx, f
movzx rax, input
mov ax, [rbx][rax * 2]
cpuid
instruction._TEXT
, (b) _DATA
, (c) _BSS
, (d) CONST
PARA
or 16 bytesdata segment align(64) 'DATA'
.
.
.
data ends
movd
movq
movaps
, movapd
, and movdqa
movups
, movupd
, and movdqu
movhps
or movhpd
movddup
pshufb
pshufd
, though pshufb
could also work(v)pextrb
, (v)pextrw
, (v)pextrd
, or (v)pextrq
(v)pinsrb
, (v)pinsrw
, (v)pinsrd
, or (v)pinsrq
pslldq
pslrdq
psllq
pslrq
pcmpgtq
instruction.and rax, -16
pxor xmm0, xmm0
pcmpeqb xmm1, xmm1
include
and
/andn
btr
or
bts
xor
btc
test
/and
bt
pext
pdep
bextr
bsf
bsr
bsf
.bsr
.popcnt
echo
(or %out
).err
=
directive!
if
, elseif
, else
, and endif
while
, for
, forc
, and endm
forc
macro
, endm
:req
after the parameter name in the macro operand field.:req
suffix.:vararg
suffix after the last macro parameter declaration.ifb
or ifnb
to see if the actual macro argument is blank.local
directive.exitm
exitm <text>
.opattr
movs
, cmps
, scas
, stos
, and lods
movs
and stos
repe
scasb
stos
lods
and stos
lods
pcmpistri
and pcmpistrm
pcmpestri
and pcmpestrm
src1
length, and RDX holds the src2
length.pcmp
Xstr
Y instructions always read 16 bytes of memory, even if the string is shorter than this, and there is the possibility of an MMU page fault when it reads data beyond the end of the string.ifndef
and endif
public
extern
and externdef
externdef
abs
proc
target: dependencies
commands
/subsystem:console
/entry:
procedure_nameMessageBox
__imp_CreateFileA
__imp_GetLastError