String in Intel speak is a 'continous sequence of bits, bytes, works, or doublewords'. So not what we normally think of as a string. Strings can be up to 2^32 -1 bytes in length.
Segmentation - 4 x 4-bit on x86, 6 x 16-bit on x64:
When the ESP or EBP register is used as a base, the SS segment is the default segment. Otherwise it's the DS segment.
Code, data, and stacks all line in one linear, continous address space references by its physcial address (0 - 2^32 for x86, 0 - 2^64 for x64. Not that on x64 only 2^46 of the 2^64 space can be populated at any one time)
A set of independent address spaces. Code, data, and stacks exist in seperate segments and is refenced by segment identifier and offset (e.g. CS:1234H. These are often called far pointers). A segment points to a description that holds the "real" address the offset is relative to.
x86 can reference up to 2^14-1 (16,383) segments of up to 2^32 bytes each (14+32=48 is why physical memory space on x64 is less than the addressable memory space).
8086 compatibilty model. Uses 64KB segments.
Instruction | Notes |
---|---|
MOV D, S | Move (S)ource into (D)estination |
LEAQ D, S | Load effective address (S) into (D) |
IMUL D,S IMULQ S MULQ S IDIVQ S DIVQ S |
Signed multiplication of rax by (S), with result placed in dx:ax Unsiged version of above. Signed divide of dx:ax by S, with result stored in dx and remainder in ax Unsigned version of abovce |
SAL D, bits SAR D, bits | (S)hift (A)rthimetic (L)eft/(R)right. Shift D bits to the (L)eft or (R)ight, preserving the highest order bit (i.e. the sign) and setting lowerest order bit to zero. |
SAR D, bits SHL D, bits | (S)hift (H)? (L)eft/(R)ight Shift D bits as above, but set highest order bit to zero. |
NEG D NOT D | Arithmetic negation of (D) e.g. 0 - D Bitwise complement of (D). e.g. 1001 -> 0110 |
CTWL CLTQ CQTO |
(C)onvert 8-bit ax (T)o 32-bit (L)ong, maintaining sign (W?) and place result in eax (C)onvert eax (L) (T)o 64-bit (Q)uardword maintaining sign and place result in rax (C)onvert rax (Q)uadword (T)o 128-bit (O)ctoword |
COM S1, S2 TEST S1, S2 | Set flags for S1-S2 Set flags for S1 boolean AND S2 ?? TODO ?? |
SETE [SETNE] SETZ [SETNZ] SETS [SETNS] SETG / SETNLE SETGE / SETNL |
(SE)t if equal / (Z)ero flag set. [Inverse] SE)t if not equal / (Z)ero flag not set. [Inverse] (SE)t if negative / (S)igned flag is set. [Inverse] (SE)t if (G)reater than / (N)ot (L)ess or (E)qual to. (SE)t if (G)reater than or (E)qual to / (N)ot (L)ess than. |
PUSHFD / POPFD | Pushes / pops the eFlags register to / from the stack ?? What does the D stand for? ?? |
name | 64-bit | 32-bit | 16-bit | 8-bit (bits 7-0) | 8-bit (bits 15-8) | Intel special use notes (p 3-11) |
---|---|---|---|---|---|---|
Register A Extended | rax | ax | ax | al | ah | Accumulator for operands and results data |
Register B Extended | rbx | bx | bx | bl | bh | Pointer to data in the DS segment |
Register C Extended | rcx | cx | cx | cl | ch | Counter for string and loop operations |
Register D Extended | rdx | dx | dx | dl | dh | I/O pointer |
Register Source Index | rsi | si | si | sil | Pointer to data in the segment pointed to by the DS register; source pointer for string operations | |
Register Destination Index | rdi | di | di | dil | Pointer to data (or destination) in the segment pointed to by the ES register; destination pointer for string operations | |
Stack Pointer | rsp | sp | sp | spl | Stack pointer (in the SS segment) | |
Base Pointer | rbp | bp | bp | bpl | Pointer to data on the stack (in the SS segment) | |
Register 8 - 15 | r8 - r15 | r8-15d | r8-15w | r8-15b |
Bit | Short name | Full name | Notes |
---|---|---|---|
0 | CF | Carry Flag | Set if borrow or carry outside of the most-significant bit of the number |
2 | PF | Parity Flag | Set if the least significant byte of the result contains an even number of 1 bits |
4 | AF | Auxillary carry Flag | Set if borrow or carry outside of bit three (used with BCD) |
6 | ZF | Zero Flag | Set is result is zero |
7 | SF | Sign Flag | Set to the most significant bit of the result (1 = negative, 0=positive) |
11 | OF | Overflow flag | Set if the result is (ignoring the sign bit) too big to fit the datatype |
Only the CF flag can be set directly (?? why would we want to? ??)
Bit | Short name | Full name | Notes |
---|---|---|---|
10 | DF | Direction flag | Controls whether string instruction (MOVS, CMPS, etc) to process downwards (set) or upwards (unset). Flag is set/unset via the STD/CLD instructions. |
movq rdi, $1
movq rsi, $15
call myAdd
# 16 returned in rax
Does the same job as MOV EAX, 0 but in fewer bytes.
Segmentation dates back to the 8086 / 8088 days (1978). The 20-bit address space (1 meg) was managed using a 4-bit segmentation register in addition to a normal 16-bit (64K) address schema. Support for four segment registers mean 256KB could be accessed without switching segments.
286 processors (1982) use the segment registers as pointers into description tables containing 24-bit base addresses (16MB), and added virtual memory management on a segment swapping basis. Segment could be marked read-only or execute-only.
386 processors (1985) introduced 32-bit processors, and a virtual 8086 mode. 32-bit means 4GB of memory support directly, but segmented also supported. Virtual memory management supported on a 4K page basis. First parallel stage support.
486 (1989) improved parallel staging. First on-chip cache (8K). Integrate FPU.
Pentium onwards (1993-...). Nothing interesting from the perspective of this level of programming.