-
Notifications
You must be signed in to change notification settings - Fork 10
/
native_considerations.txt
103 lines (69 loc) · 3.08 KB
/
native_considerations.txt
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
I thought about using the ref.x86asm first, but there was a better one
that was pointed to me: https://github.com/google/CPU-instructions
I found this really helpful when thinking about the problem of compiling
software: https://agner.org/optimize/
google/CPU-instructions can be useful.
Overflow and carry
http://teaching.idallen.com/dat2343/10f/notes/040_overflow.txt
- On unsigned numbers, if carry flag is set, the result is wrong.
On signed numbers, if overflow flag is set, the result is wrong.
1111 + 0001 = 0000 (carry flag is turned on)
0000 - 0001 = 1111 (carry flag is turned on)
0100 + 0100 = 1000 (overflow flag is turned on)
1000 + 1000 = 0000 (overflow flag is turned on)
0100 + 0001 = 0101 (overflow flag is turned off)
0110 + 1001 = 1111 (overflow flag is turned off)
1000 + 0001 = 1001 (overflow flag is turned off)
1100 + 1100 = 1000 (overflow flag is turned off)
if both numbers are positive and the result is negative.
or both numbers are negative and the result is positive.
Then overflow is set, otherwise it is cleared.
Outcome into flags
Add/Sub -- sets all flags properly
MUL sets OF and CF to 0 if upper half of results is 0
DIV scrambles flags
AND (and maybe other logic) sets the ZF/FP/SF
FLAGS register
- MOV/LEA does not set FLAGS
- When they do, the jump outcome is affected by
destination value: ZF(zero)/PF(parity)/SF(sign)
operation's type (add,sub,mul...): CF/OF
whether the destination register is ECX
ModRM byte
At r/m byte, disallow *SP(r4) at [r4] and [r4*{1,2,4,8} + x]
Mode:2 R/M:3 Reg:3
Scale:2 Base:3 Index:3
At r/m [r5] means for disp32
So set mod=00 to mod=01 if r/m field is r5
At Index=5:
MOD=00 means [scaled index] + disp32
MOD=01 means [scaled index] + disp8 + [EBP]
MOD=10 means [scaled index] + disp32 + [EBP]
RIP relative addressing:
mod = 00, r/m = 101 results in: RIP + disp32
the SIB works like usual and can be shifted in.
Overall instruction encoding
Legacy prefixes, REX, Opcode, ModR/M SIB Displacement, Immediate
Strategy:
Place Opcode
Encode Prefixes, REX & ModR/M together.
Place immediate if exists.
66, 67, F2, F3, they are thrown before REX.W if the flag
not present in the specification.
If REX.W is marked, it must be present.
0100
(no 8) Operand size determined by CS.D
(8) 64-bit operand size
(4)REX.R (ModR/M reg field)
(2)REX.X (SIB index field)
(1)REX.B (opcode reg, SIB base field, ModRM R/M field)
Instruction summary:
REX.W indicates there is a REX prefix, if legacy instructions are
promoted into 64-bit behavior, then they are not listed with REX.W
/digit indicates that the reg field in ModR/M is part of the opcode.
cb, cw, cd, cp, co, ct -- 1,2,4,6,8,10 byte value following opcode.
ib, iw, id, io -- 1,2,4,8 immediate operand after modrm
+rb +rw +rd +ro -- (opcode reg) lower 3 bits of opcode encodes register.
{1,2,4,8} reg size.
+i add ST(i) operand from FPU stack to the hexadecimal
value of the last byte