inline assembly with Visual C++ tutorial
compliments the examples,
also contains simple instruction list
First off let me explain that this was
a request from some email I got about
how this works
Anyway enough of my situation, here is the information:
using inline assembly
Within the C++ language is a keyword
_asm
{
}
Within the block contains the assembly mnemonics/instructions.
There not very hard to use, it usually contains a instruction followed by its operands. The operands usually contain registers, memory,
memory addresses, and constant numbers. Normally in assembly language
every line of code, assembles to one line of machine instructions.
However this isnt always true, there are exceptions. A simple example
of the use of a instruction is the following
mov eax,1
Now before we can truly really understand this instruction we have
to understand a few other things which are important. Machine languages
are priority languages, and therefore are designed to work for a specific
type of chip. So they work in specific ways and in the x86 chip there are built in high speed memory locations called registers. These registers
are used for data being passed in from memory, or other places to be
manipulated, and then passed back out into memory or other places. Its
kind of like you got to put the information in specific spots it can directly
get to and then setup and call the instruction. What the above example
means is mov into register eax the hex value 1. The comma separates the
operands. Registers have different sizes, since the registers the cpu's evolved over time. The metaphor Jeff Duntermann makes in his book
which I really recommend it taught me assembly quick and easily is " Assembly Language Step-Step", is " Adding a room to your house doesn't make it two houses--just one bigger house. And so it has been with the x86 registers."
There are multiple types of registers some have specific tasks like the
IP register (Instruction Pointer), Segment Registers, etc. The registers
I am involved with in this example are just the general purpose registers
which I am going to explain here The newer general purpose registers are much more general. In past days
specific registers had certain agendas but these were actually limitations
with the cpu. Now days the general purpose registers fall into three classes.
The 32 bit general purpose registers, the 16 bit general purpose registers,
and the 8 bit register halves. What should be noted however is that these
registers are not really 3 distinct separate classes of information. These
names really stand for regions of memory. How this is accomplished is done
by a little naming system. The 16 bit registers and 8 bit register halves
are really inside the 32 bit registers, and are just specific sections of memory.
In a 32 bit register there are 32 bits. Look at the following graph:
ax
HI | ah al LOW
1111 1111 1111 1111 1111 1111 1111 1111 - register eax(full 32 bits)
The register eax is the full 32 bits of this memory location. The register
ax is the lower half, or the low 16 bits. Register ah is the high half
of the low 16 bits. al is the low 8 bits of ax (the low 16 bits). This
can sound of tricky at first but soon as you understand the notation you
can know how to pick out registers to use with your instructions. Its kind of
you move stuff from places into the registers, and then use them in accordance
with instructions, and then move the changes around to different places. Check
out this notation example
General purpose Register eax
eax - full 32 bits
ax - low 16 bits
ah - high 8 bit register half
al - low 8 bit register half
ebx - full 32 bits
bx - low 16 bits
bh - high 8 bit register half
bl - low 8 bit register half
ecx - full 32 bits
cx - low 16 bits
ch - high 8 bit register half
cl - low 8 bit register half
edx - full 32 bits
dx - low 16 bits
dh - high 8 bit register half
dl - low 8 bit register half
Now that we understand the notion of the registers we an continue to use
them with memory locations and other types of data. But what were going to explain
here is just inline assembly. Since C++ hides most of its inner workings on how
the actual code is outputted we can literally use C++ variables directly
within your inline assembly. You can create functions that pass variables
that can be manipulated with inline assembly, you can do all
kinds of neat stuff. Here is a simple code snippet:
int __fastcall exampleadd(int x, int y)
{
int rt = 0;
_asm
{
mov eax,x
mov ebx,y
add eax,ebx
mov rt,eax
}
return rt;
}
This is a function which uses register based calling conventions which are pretty
useful when you want just a little bit extra speed. Lets explain the code.
mov eax,x
Means move into register eax (the full 32 bit register) the value within the
variable x (VC when it compiles replaces this with the correct information).
mov ebx,y
Means move into register ebx (the full 32 bit register) the value within the
variable y (VC when it compiles replaces this with the correct information).
add eax,ebx
This means add the integer values in eax , with the values in ebx and put the values
back into eax.
mov rt,eax
Means move the value from register eax into the location where the variable
rt is at.
I hope I gave some light on this subject there's allot of really great tutorials
on the internet if you just look so yeah see ya.
- Jared
PS:
Here is a simple list of the instruction set I got from opcodes.txt
If your interested in understanding the instructions further I suggest
going and getting a guide to the instruction set.
8086/80186/80286/80386/80486 Instruction Set
AAA - Ascii Adjust for Addition
AAD - Ascii Adjust for Division
AAM - Ascii Adjust for Multiplication
AAS - Ascii Adjust for Subtraction
ADC - Add With Carry
ADD - Arithmetic Addition
AND - Logical And
ARPL - Adjusted Requested Privilege Level of Selector (286+ PM)
BOUND - Array Index Bound Check (80188+)
BSF - Bit Scan Forward (386+)
BSR - Bit Scan Reverse (386+)
BSWAP - Byte Swap (486+)
BT - Bit Test (386+)
BTC - Bit Test with Compliment (386+)
BTR - Bit Test with Reset (386+)
BTS - Bit Test and Set (386+)
CALL - Procedure Call
CBW - Convert Byte to Word
CDQ - Convert Double to Quad (386+)
CLC - Clear Carry
CLD - Clear Direction Flag
CLI - Clear Interrupt Flag (disable)
CLTS - Clear Task Switched Flag (286+ privileged)
CMC - Complement Carry Flag
CMP - Compare
CMPS - Compare String (Byte, Word or Doubleword)
CMPXCHG - Compare and Exchange
CWD - Convert Word to Doubleword
CWDE - Convert Word to Extended Doubleword (386+)
DAA - Decimal Adjust for Addition
DAS - Decimal Adjust for Subtraction
DEC - Decrement
DIV - Divide
ENTER - Make Stack Frame (80188+)
ESC - Escape
HLT - Halt CPU
IDIV - Signed Integer Division
IMUL - Signed Multiply
IN - Input Byte or Word From Port
INC - Increment
INS - Input String from Port (80188+)
INT - Interrupt
INTO - Interrupt on Overflow
INVD - Invalidate Cache (486+)
INVLPG - Invalidate Translation Look-Aside Buffer Entry (486+)
IRET/IRETD - Interrupt Return
Jxx - Jump Instructions Table
JCXZ/JECXZ - Jump if Register (E)CX is Zero
JMP - Unconditional Jump
LAHF - Load Register AH From Flags
LAR - Load Access Rights (286+ protected)
LDS - Load Pointer Using DS
LEA - Load Effective Address
LEAVE - Restore Stack for Procedure Exit (80188+)
LES - Load Pointer Using ES
LFS - Load Pointer Using FS (386+)
LGDT - Load Global Descriptor Table (286+ privileged)
LIDT - Load Interrupt Descriptor Table (286+ privileged)
LGS - Load Pointer Using GS (386+)
LLDT - Load Local Descriptor Table (286+ privileged)
LMSW - Load Machine Status Word (286+ privileged)
LOCK - Lock Bus
LODS - Load String (Byte, Word or Double)
LOOP - Decrement CX and Loop if CX Not Zero
LOOPE/LOOPZ - Loop While Equal / Loop While Zero
LOOPNZ/LOOPNE - Loop While Not Zero / Loop While Not Equal
LSL - Load Segment Limit (286+ protected)
LSS - Load Pointer Using SS (386+)
LTR - Load Task Register (286+ privileged)
MOV - Move Byte or Word
MOVS - Move String (Byte or Word)
MOVSX - Move with Sign Extend (386+)
MOVZX - Move with Zero Extend (386+)
MUL - Unsigned Multiply
NEG - Two's Complement Negation
NOP - No Operation (90h)
NOT - One's Compliment Negation (Logical NOT)
OR - Inclusive Logical OR
OUT - Output Data to Port
OUTS - Output String to Port (80188+)
POP - Pop Word off Stack
POPA/POPAD - Pop All Registers onto Stack (80188+)
POPF/POPFD - Pop Flags off Stack
PUSH - Push Word onto Stack
PUSHA/PUSHAD - Push All Registers onto Stack (80188+)
PUSHF/PUSHFD - Push Flags onto Stack
RCL - Rotate Through Carry Left
RCR - Rotate Through Carry Right
REP - Repeat String Operation
REPE/REPZ - Repeat Equal / Repeat Zero
REPNE/REPNZ - Repeat Not Equal / Repeat Not Zero
RET/RETF - Return From Procedure
ROL - Rotate Left
ROR - Rotate Right
SAHF - Store AH Register into FLAGS
SAL/SHL - Shift Arithmetic Left / Shift Logical Left
SAR - Shift Arithmetic Right
SBB - Subtract with Borrow/Carry
SCAS - Scan String (Byte, Word or Doubleword)
SETAE/SETNB - Set if Above or Equal / Set if Not Below (386+)
SETB/SETNAE - Set if Below / Set if Not Above or Equal (386+)
SETBE/SETNA - Set if Below or Equal / Set if Not Above (386+)
SETE/SETZ - Set if Equal / Set if Zero (386+)
SETNE/SETNZ - Set if Not Equal / Set if Not Zero (386+)
SETL/SETNGE - Set if Less / Set if Not Greater or Equal (386+)
SETGE/SETNL - Set if Greater or Equal / Set if Not Less (386+)
SETLE/SETNG - Set if Less or Equal / Set if Not greater or Equal
SETG/SETNLE - Set if Greater / Set if Not Less or Equal (386+)
SETS - Set if Signed (386+)
SETNS - Set if Not Signed (386+)
SETC - Set if Carry (386+)
SETNC - Set if Not Carry (386+)
SETO - Set if Overflow (386+)
SETNO - Set if Not Overflow (386+)
SETP/SETPE - Set if Parity / Set if Parity Even (386+)
SETNP/SETPO - Set if No Parity / Set if Parity Odd (386+)
SGDT - Store Global Descriptor Table (286+ privileged)
SIDT - Store Interrupt Descriptor Table (286+ privileged)
SHL - Shift Logical Left
SHR - Shift Logical Right
SHLD/SHRD - Double Precision Shift (386+)
SLDT - Store Local Descriptor Table (286+ privileged)
SMSW - Store Machine Status Word (286+ privileged)
STC - Set Carry
STD - Set Direction Flag
STI - Set Interrupt Flag (Enable Interrupts)
STOS - Store String (Byte, Word or Doubleword)
STR - Store Task Register (286+ privileged)
SUB - Subtract
TEST - Test For Bit Pattern
VERR - Verify Read (286+ protected)
VERW - Verify Write (286+ protected)
WAIT/FWAIT - Event Wait
WBINVD - Write-Back and Invalidate Cache (486+)
XCHG - Exchange
XLAT/XLATB - Translate
XOR - Exclusive OR