SlideShare a Scribd company logo
1 of 49
Download to read offline
1
C & ASM
AN INTRODUCTION
Arun Umrao
www.sites.google.com/view/arunumrao
DRAFT COPY - GPL LICENSING
2
Contents
1 ASM in C 9
1.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.2 Extended ASM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.2.1 Volatile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.3 Operand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.4 Clobber List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.5 Constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.5.1 Common Constraints . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.5.2 Constraint Modifiers . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.6 Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Addition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Bitwise AND . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Clear Carry Flag . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Compare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Copy Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Decrements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Increments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Jump if Above . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Jump to Address . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Store Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Negative of Number . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Bitwise Not . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Bitwise OR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Rotate Bits Left Through Carry . . . . . . . . . . . . . . . . . . . 27
Rotate Bits Right Through Carry . . . . . . . . . . . . . . . . . . 27
Rotate to Left . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Rotate to Right . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Set Carry Flag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Subtract . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Bitwise Exclusive OR . . . . . . . . . . . . . . . . . . . . . . . . . 31
2 C in ASM 33
2.1 NASM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
2.1.1 Memory Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
2.1.2 Defining Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
2.1.3 Character Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
2.1.4 Local Label . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
2.1.5 Local Variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
2.1.6 Repeat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
2.1.7 Directives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
2.1.8 NASM File Layout . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
2.1.9 Calling External Functions . . . . . . . . . . . . . . . . . . . . . . 41
2.1.10 Uers’s Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
2.1.11 Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
3
2.1.12 Executing Command . . . . . . . . . . . . . . . . . . . . . . . . . . 50
2.2 Link ASM with C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
4 ASM in C
1.1. INTRODUCTION 5
1ASM in C
In this chapter we shall discuss that how assembly codes can be executed within C
codes. For this purpose, I use NetBean IDE with Cygwin compiler. Cygwin has default
assembler as.exe. The representation of instructions and register symbols depend on the
assembler type. For example, usage of mov instruction on a 32-bit architecture, GAS
syntax is:
✞
1 ;instruction source , destination
movl $0x000F , %eax ; Store the value F into the ax register
✌
✆
Some instructions, especially when built for Unix, Linux, etc., require the use of suffixes
to specify the size of the data which will be the subject of the operation. For example,
some possible suffixes are ‘b’ for byte (8 bits), ‘w’ for word (16 bits), ‘l’ for long (32 bits)
and ‘q’ for quad (64 bits). For 64-bits assembly programming, ‘R’ is prefixed with each
registers.
✞
movq $6 , %rax ; 64 bits code
✌
✆
But on Intel Syntax we don’t have to use the suffix. Based on the register name and the
used immediate value the compiler knows which data size to use. For example,
✞
1 ;instruction destination , source
MOV EAX , 0 x000F
✌
✆
Therefore, while you are writing your assembly codes, please be careful about the as-
sembler, OS and processor architecture type. Instruction OP codes, register name and
hexadecimal data values are case insensitive, i.e. they can be written in upper case or in
lower case or in mixed case to increase readability of the assembly codes. gcc has also
capability to de-assemble the .c file into .asm file by using following command.
✞
gcc -S myc.c -o myc.asm ; Note for CAPITAL S
✌
✆
gcc generates an equivalent assembly file. This assembly file can be compiled into exe-
cutable with gcc by using following command.
✞
1 gcc -o <outfile name > -m32 <asm file >
✌
✆
Here, gcc calls the assembler (as) and the linker (ld) automatically to compile the assembly
file. ‘-m32’ can be replaced with ‘-m64’ for 64-bits processors.
1.1 Introduction
The format of basic inline assembly is very much straight forward. Its basic form is
6 ASM in C
✞
1 asm(<assembly code >);
✌
✆
We can write inline code in modified form if asm function is conflict with other same ‘c’
function .
✞
1 __asm__(< assembly code >);
✌
✆
1.2 Extended ASM
In basic inline assembly, there are only instructions. In extended assembly, we can also
specify the operands. It allows us to specify the input registers, output registers and a
list of clobbered registers.
✞
1 __asm__ (assembler template
: /* Optional output operands */
3 : /* Optional input operands */
: /* Optional list of clobbered registers */
5 : /* Jump to Goto Labels (optional ) */
);
✌
✆
The assembler template consists of assembly instructions. Each operand is described
by an operand-constraint string followed by the C expression in parentheses. A colon (:)
separates the assembler template from the first output operand and another separates the
last output operand from the first input, if any. Commas separate the operands within
each group. The total number of operands is limited to ten or to the maximum number
of operands in any instruction pattern in the machine description, whichever is greater.
✞
#include <stdio.h>
2
int main () {
4 int in = 10, out;
__asm__ ("movl %1, %% eax;"
6 "movl %%eax , %0;"
: "=r" (out) /* Output */
8 : "r" (in) /* Input */
: "%eax" /* Clobbered Register */
10 );
printf("Output is %dn", out);
12 return 0;
}
✌
✆
✞
Output is 10
✌
✆
Here it is made the value of C variable ‘out’ equal to that of C variable ‘in’ using assembly
instructions. Here C variable ‘out’ is the output operand, referred to by %0 and C variable
‘in’ is the input operand, referred to by %1. r is a constraint on the operands. For the
time being, r says to GCC to use any register for storing the operands. Output operand
1.2. EXTENDED ASM 7
constraint should have a constraint modifier “=”. And this modifier says that it is the
output operand and is write-only. There are two %’s prefixed to the register name. This
helps GCC to distinguish between the operands and registers. Operands have a single
% as prefix. The clobbered register %eax after the third colon tells GCC that the value
of %eax is to be modified inside asm, so GCC won’t use this register to store any other
value. When the execution of asm is complete, ‘out’ will reflect the updated value, as it
is specified as an output operand. In other words, the change made to C variable ‘out’
inside asm is supposed to be reflected outside the asm. Again, we can also get multiple
outputs by accessing suitable registers as shown in the following example.
✞
1 #include <stdio.h >
3 int main () {
int out1 , out2 ;
5 __asm__ ("movl $8 , %% eax;"
"movl $10 , %% ebx;"
7 : "=a" (out1 ), "=b" (out2 )
);
9 printf("%d, %d", out1 , out2 );
return 0;
11 }
✌
✆
✞
8, 10
✌
✆
The size of operand is crucial to determine the space required for execution of the op-code
command. The size of memory operands is determined from the last character of the op-
code name. For example, movl represents to the op-code mov which is being operated
on the long data type. Similarly, other suffixes are ‘b’ for byte, ‘w’ for (16-bit) word, and
‘l’ for (32-bit) long. The symbol ‘$’ prefixed with a number tells to gcc that, the number
value followed by it is immediately assigned to the register. Indexing or indirection is
done by enclosing the index register or indirection memory cell address in parentheses.
✞
1 movl 8(%% ebp), %% eax
✌
✆
instruction tells that, the contents at offset 8 from the memory cell pointed to by ‘%ebp’
register is moved into into the register ‘%eax’.
1.2.1 Volatile
The assembly codes in C are very susceptible to dangle beyond the scope of asm function.
And it is a security reason to control their scope. Our assembly statement must execute
where we put it, and they must not be moved out of a loop as an optimization. To do
this, we put keyword “volatile” or “ volatile ” just after asm or “ asm ” and before
the ()s. Its syntax is given below:
✞
1 __asm__ __volatile__ ( "...; "
"...; " : ... );
✌
✆
Example of use of volatile is given below:
8 ASM in C
✞
#include <stdio.h>
2
int main () {
4 int in = 10, out = 5;
6 __asm__ __volatile__ (
"addl %%ebx , %% eax"
8 /* Update var out by value of eax register */
: "=a" (out)
10 : "a" (in), "b" (out)
);
12 printf("in + out = %dn", out);
return 0;
14 }
✌
✆
✞
in + out = 15
✌
✆
1.3 Operand
C Language Expressions (CLE) or C Language Variables (CLV) serve as operands for
the assembly instructions inside asm. Each operand is a combination of constraints in
double quote followed by C language variable or C language expression in parentheses.
Prototype is
✞
1 "constraint " (< CLV >)
✌
✆
Constraints are primarily used to decide the addressing modes for operands. They are
also used in specifying the registers to be used. If we use more than one operand, then
they are separated by comma. In the assembler template, each operand is referenced
by numbers from zero to n operands (including input and output both). First is output
operand and it is numbered 0. Next are input operands which are counted from 1 to n−1.
Output operand expressions must be left-values. The input operands are not restricted
like this. Ordinary output operands must be write-only. Extended asm also supports
input-output or read-write operands.
Illustrated Example Assume that, we have to add 5 to the input value 10 and the
answer should be retrieved through another variable. See the example below:
✞
1 #include <stdio.h>
3 int main () {
int in1 = 10, in2 = 5, out;
5 __asm__ ("movl %1, %% eax;"
/* Operator , register , 2nd input*/
7 "add %%eax , %2;"
/* Output : "constraints " (<CLV >) */
9 : "=r" (out)
/* Two inputs : "constraints " (<CLV >) *
1.3. OPERAND 9
11 * Input count (%1) started right to left */
: "r" (in2), "r" (in1)
13 : "%eax" /* Clobbered register */
);
15 printf("in1 + in2 is %d", out);
return 0;
17 }
✌
✆
✞
in1 + in2 is 15
✌
✆
Here inputs are ‘in2’ and ‘in1’. Output is directly fetched from the register. Here, one
point is to be noted that, register eax is prefixed with % symbol and also with %% symbol
at different places. It is because the compiler copies the assembler instructions in a basic
asm verbatim to the assembly language output file, without processing dialects or any of
the ‘%’ operators that are available with extended asm. This results in minor differences
between basic asm strings and extended asm templates. For example, to refer to registers
you might use ‘%eax’ in basic asm and ‘%%eax’ in extended asm. Now if we want to
specify the register then constraints representing to the register are used as shown in the
following table.
✞
1 #include <stdio.h>
3 int main () {
int in1 = 10, in2 = 5, out;
5 __asm__ ("addl %%ebx , %% eax;"/* Add BX to AX register */
"movl %%eax , %% ecx;"/* Move value of AX to CX*/
7 /* Output : "register constraints " (<CLV >) */
: "=c" (out)
9 /* Inputs : "register constraints " (<CLV >) */
: "a" (in2), "b" (in1)
11 );
printf("in1 + in2 is %d", out);
13 return 0;
}
✌
✆
✞
in1 + in2 is 15
✌
✆
In above two examples, we didn’t put any register to the clobber list to let the free to
GCC to decide it. As the constraints for input variable ‘in2’ is a, hence this input is
directly stored in the register eax. Similarly, the constraints for input variable ‘in1’ is b,
hence this input is directly stored in the register ebx. We move the result stored in eax
to ecx register as constants of output variable ‘out’ is c, i.e. register ecx. We can assign
a value directly to a register. To do so, movl command is used and value is preceded by
‘$’ sign as explained in the following example.
✞
1 #include <stdio.h>
3 int main () {
int out;
10 ASM in C
5 /* Add 10 and 20 and store *
*result into register %eax*/
7 __asm__ ("movl $10 , %% eax;"
"movl $20 , %% ebx;"
9 "addl %%ebx , %% eax;"
: "=a" (out)
11 );
printf("Sum is %d", out);
13 return 0;
}
✌
✆
✞
Sum is 30
✌
✆
In case of you do not want to use any constraints, it is leaved blank after “:” symbol as
shown in the following example.
✞
1 #include <stdio.h>
3 int main () {
int out;
5 /* Add 10 and 20 and store *
*result into register %eax*/
7 __asm__ ("movl $10 , %% eax;"
"movl $20 , %% ebx;"
9 "addl %%ebx , %% eax;"
: "=r" (out)
11 : /* Order should be maintained */
: "%ebx"
13 );
printf("Sum is %d", out);
15 return 0;
}
✌
✆
✞
Sum is 30
✌
✆
1.4 Clobber List
Registers are used to store inputs and outputs by the GCC. If we use the r constraint
type then GCC itself selects the registers in which inputs and outputs are to be stored.
This is why, the output register is remains unknown to the user. This is why, we inform
GCC that we will use and modify the specific register. Clobber list is the register name
placed after third “:” operator as shown below:
✞
1 #include <stdio.h>
3 int main () {
int in1 = 10, in2 = 5, out;
5 __asm__ ("movl %1, %% eax;"
1.5. CONSTRAINTS 11
"add %%eax , %2;"
7 : "=r" (out) /* Output */
: "r" (in2), "r" (in1) /* Inputs */
9 : "%eax" /* Clobbered Register */
);
11 printf("in1 + in2 is %d", out);
return 0;
13 }
✌
✆
✞
in1 + in2 = 15
✌
✆
In Clobber list, those registers are defined which are not present either in input or in the
output constraint list.
1.5 Constraints
Constraints tells whether an operand is a register and which kind of it is. Similarly, it
tells whether operand is a memory reference and which kinds of memory address is¿ It
also tells that whether the operand is an immediate constant and what value it stored.
1.5.1 Common Constraints
There are a number of constraints of which only a few are used frequently. We’ll have a
look at those constraints.
Register Operand Constraint(r) When operands are specified using this constraint,
they get stored in General Purpose Registers(GPR). Take the following example:
✞
1 __asm__ (
"movl %%eax , %0n"
3 :"=r" (<my C variable >)
);
✌
✆
Here the variable ‘my C variable’ is kept in a register, the value in register eax is copied
onto that register, and the value of ‘my C variable’ is updated into the memory from this
register. When the r constraint is specified, GCC may keep the variable in any of the
available GPRs. To specify the register, you must directly specify the register names by
using specific register constraints. They are:
12 ASM in C
Constraints Register (s)
a %eax, %ax, %al
b %ebx, %bx, %bl
c %ecx, %cx, %cl
d %edx, %dx, %dl
S %esi, %si
D %edi, %di
Memory Operand Constraint(m) When the operands are in the memory, any operations
performed on them will occur directly in the memory location, as opposed to register
constraints, which first store the value in a register to be modified and then write it back
to the memory location. But register constraints are usually used only when they are
absolutely necessary for an instruction or they significantly speed up the process. Memory
constraints can be used most efficiently in cases where a C variable needs to be updated
inside asm and you really don’t want to use a register to hold its value. For example, the
value of ‘idtr’ is stored in the memory location:
✞
__asm__ (
2 "sidt %0n"
:
4 :"m" (<memory location >)
);
✌
✆
Matching(Digit) Constraints In some cases, a single variable may serve as both the
input and the output operand. Such cases may be specified in asm by using matching
constraints.
✞
1 __asm__ (
"incl %0"
3 :"=a" (<C Language Variable >)
:"0" (<C Language Variable >)
5 );
✌
✆
We saw similar examples in operands subsection also. In this example for matching
constraints, the register %eax is used as both the input and the output variable. var
input is read to %eax and updated %eax is stored in var again after increment. “0” here
specifies the same constraint as the 0th output variable. That is, it specifies that the
output instance of var should be stored in %eax only. This constraint can be used:
New Case In cases where input is read from a variable or the variable is modified and
modification is written back to the same variable.
New Case In cases where separate instances of input and output operands are not
necessary.
1.5. CONSTRAINTS 13
The most important effect of using matching restraints is that they lead to the efficient
use of available registers.
r Explanation
“m” A memory operand is allowed, with any kind of ad-
dress that the machine supports in general
“o” A memory operand is allowed, but only if the address
is offset table, i.e. adding a small offset to the address
gives a valid address
“V” A memory operand that is not offset table. In other
words, anything that would fit the ‘m’ constraint but
not the ‘o’constraint
“i” An immediate integer operand (one with constant
value) is allowed. This includes symbolic constants
whose values will be known only at assembly time
“n” An immediate integer operand with a known nu-
meric value is allowed. Many systems cannot sup-
port assembly-time constants for operands less than
a word wide. Constraints for these operands should
use ‘n’ rather than ‘i’
“g” Any register, memory or immediate integer operand
is allowed, except for registers that are not general
registers
See the example given below:
✞
1 #include <stdio.h>
3 int main () {
int in1 = 10, in2 = 5;
5
__asm__ __volatile__ ("lock ;n"
7 "addl %1, %0; n"
: "=m" (in1)
9 : "ir" (in2), "m" (in1)
);
11 printf("in1 + in2 = %dn", in2);
return 0;
13 }
✌
✆
✞
in1 + in2 = 15
✌
✆
This is an atomic addition. We can remove the instruction ‘lock’ to remove the atomicity.
In the output field, =m says that ‘b’ is an output and it is in memory. Similarly, ir says
14 ASM in C
that, ‘a’ is an integer and should reside in some register. No registers are in the clobber
list. Following constraints are x86 specific.
Constraints Explanation
Constraints Register Operand Constraint
“q” Registers a, b, c or d
“I” Constant in range 0 to 31 (for 32-bit shifts)
“J” Constant in range 0 to 63 (for 64-bit shifts)
“K” 0xff
“L” 0xffff
“M” 0, 1, 2, or 3 (shifts for lea instruction)
“N” Constant in range 0 to 255 (for out instruction)
“f” Floating point register
“t” First (top of stack) floating point register
“u” Second floating point register
“A” Specifies the ‘a’ or ‘d’ registers. This is primarily use-
ful for 64-bit integer values intended to be returned
with the ‘d’ register holding the most significant bits
and the ‘a’ register holding the least significant bits
1.5.2 Constraint Modifiers
While using constraints, for more precise control over the effects of constraints, GCC
provides us with constraint modifiers. Mostly used constraint modifiers are
Constraints Explanation
“=” Means that this operand is write-only for this in-
struction; the previous value is discarded and re-
placed by output data
“&” Means that this operand is an early clobber operand,
which is modified before the instruction is finished
using the input operands. Therefore, this operand
may not lie in a register that is used as an input
operand or as part of any memory address. An input
operand can be tied to an early clobber operand if
its only use as an input occurs before the early result
is written
1.6. INSTRUCTIONS 15
1.6 Instructions
In this section important operators are explained by giving suitable examples. The similar
operators can be used similarly. in GCC, asm instruction set direction is from left to
right, i.e. for example, add instruction has syntax like
✞
1 add <source register >, <destination register >;
✌
✆
Each instruction is terminated by “;” symbol. If constraint type is r then, GCC automat-
ically select the register for input and output. If constraint type is not r then instruction
sets are executed according to the above syntax.
Addition
add instruction adds the contents of two source and destination operands and stores the
sum in destination register. See the example below:
✞
1 #include <stdio.h>
3 int main () {
int in = 10, out;
5 __asm__ ("movl %1, %% eax;"
"addl %%eax , %1;"/* Operator , register , input*/
7 : "=r" (out) /* Output , auto constraint */
: "r" (in) /* One input , auto constraint */
9 : "%eax" /* Clobbered register */
);
11 printf("out is %d", out);
return 0;
13 }
✌
✆
✞
out is 20
✌
✆
Here, constraint type is r, hence the data is stored in any register and it is decided by
GCC and register is selected by Clobbered Register list. This is why, in above example,
sum of register eax and input is stored in eax register. We can supply the input value
directly rather than through usual inputs. Here decimal 52 is supplied to AX register
directly.
✞
1 #include <stdio.h>
3 int main () {
int in = 10, out;
5 __asm__ ("movl $52 , %% eax;"
"addl %%eax , %1;"/* Operator , register , input */
7 : "=r" (out) /* Output , auto constraint */
: "r" (in) /* One input , auto constraint */
9 : "%eax" /* Clobbered register */
);
11 printf("out is %d", out);
16 ASM in C
return 0;
13 }
✌
✆
✞
out is 62
✌
✆
Another example of summation.
✞
1 #include <stdio.h>
3 int main () {
int in1 = 10, in2 = 17, out;
5 __asm__ ("movl $52 , %% eax;"
"addl %%eax , %2;"
7 /* Output , auto constraint */
: "=r" (out)
9 /* Two inputs , auto constraint */
: "r" (in2), "r" (in1)
11 : "%eax" /* Clobbered register */
);
13 printf("out is %d", out);
return 0;
15 }
✌
✆
✞
out is 69
✌
✆
Bitwise AND
AND is short name of Bitwise AND. The output is 1 if both operand bits are 1 and
otherwise their AND is 0.
✞
1 0010 0101 : X=37
0101 0010 : Y=82
3 ---------------- AND
0000 0000 : 0
✌
✆
See the example below:
✞
#include <stdio.h>
2
int main () {
4 int out;
__asm__ ("movl $37 , %% eax;"
6 "movl $82 , %% ebx;"
"and %%eax , %% ebx;"
8 : "=b" (out)
);
10 printf("AND of 37 and 82 is %d", out);
return 0;
12 }
✌
✆
1.6. INSTRUCTIONS 17
✞
AND of 37 and 82 is 0
✌
✆
The ANDed result of two operands is stored in second register, i.e. in ebx register.
Clear Carry Flag
clc instruction clears the previously set carry flag. To see its working, two consecutive
examples are given. In the following example, carry flag is set to high. Thus a jump is
take place to ‘HERE’ offset. This skips the increment of eax register. So the final output
is −10.
✞
1 #include <stdio.h>
3 int main () {
int out;
5 __asm__ ("movl $10 , %% eax;"
"stc;" /* Set carry flag .*/
7 "jc HERE ;" /* Jump to HERE .*/
"inc %% eax;" /* Skipped.*/
9 "HERE : ;"
"neg %% eax;" /* Executed */
11 : "=a" (out)
);
13 printf("Negative of 10 is %d", out);
return 0;
15 }
✌
✆
✞
Negative of 10 is -10
✌
✆
In the above example, clc instruction is placed just below to stc instruction. It skips the
jump on carry and inc instruction is executed. Now the final value is −11.
✞
1 #include <stdio.h>
3 int main () {
int out;
5 __asm__ ("movl $10 , %% eax;"
"stc;" /* Set carry flag .*/
7 "clc;" /* Clear carry flag .*/
"jc HERE ;" /* No jump to HERE */
9 "inc %% eax;" /* Executed */
"HERE : ;"
11 "neg %% eax;" /* Executed */
: "=a" (out)
13 );
printf("Negative of 10 is %d", out);
15 return 0;
}
✌
✆
18 ASM in C
✞
Negative of 10 is -11
✌
✆
Compare
cmp compares the source operand from the destination operand. It updates the flags as
the sub instruction. It does not alter the source and destination operands. Flags are
sets according to: if first operand is equal to second operand (ZF = 1 and CF = 0), first
operand is less than the second operand (ZF = 1 and CF = 1) or first operand is greater
than the second operand (ZF = 0 and CF = 0). According to this result, jump function
is executed.
✞
1 #include <stdio.h>
3 int main () {
int out;
5 __asm__ ("movl $1 , %% eax;" /*AX = 1 */
"movl $10 , %% ebx;" /*BX = 10*/
7 "movl $15 , %% ecx;" /*CX = 15*/
"A : ;" /* Loop offset*/
9 "inc %% eax;" /*AX = AX + 1*/
"addl %%ebx , %% ecx;"/*CX = CX + BX*/
11 "cmp %%eax , %% ebx;" /*ZF = CF = 0, if AX > BX*/
"ja A;" /* Jump to Offset */
13 : "=c" (out)
);
15 printf("Output is %d", out);
return 0;
17 }
✌
✆
✞
Output is 105
✌
✆
Copy Data
mov instruction with proper suffix (i.e. ‘b’ for 8 bits byte data, ‘w’ for 16 bits word data,
‘l’ for 32 bits long data and ‘q’ for 64 bits quad data) to copy data into registers. See the
example below:
✞
1 #include <stdio.h>
3 int main () {
char *in1="This is my string";
5 char *out;
__asm__ ("movl %1, %% eax;"
7 /* Output , auto constraint */
: "=r" (out)
9 /* Two inputs , auto constraint */
: "r" (in1)
1.6. INSTRUCTIONS 19
11 : "%eax" /* Clobbered register */
);
13 printf("out is ’%s’", out);
return 0;
15 }
✌
✆
✞
out is ’This is my string ’
✌
✆
mov instruction accepts two arguments, first is source and second is destination in GAS
assembler.
Decrements
dec subtracts one from the operand, it does not affect CF. If value of operand is decimal
52 then it shall made this value to 52 − 1 = 51.
✞
1 #include <stdio.h>
3 int main () {
int out;
5 __asm__ ("movl $52 , %% eax;"
"dec %% eax;"
7 : "=a" (out)
);
9 printf("out is %d", out);
return 0;
11 }
✌
✆
✞
out is 51
✌
✆
Increments
It increments the value of operands by one. If value of operand is decimal 52 then it shall
made this value to 52 + 1 = 53.
✞
1 #include <stdio.h>
3 int main () {
int out;
5 __asm__ ("movl $52 , %% eax;"
"inc %% eax;"
7 : "=a" (out)
);
9 printf("out is %d", out);
return 0;
11 }
✌
✆
✞
out is 53
✌
✆
20 ASM in C
Jump if Above
ja is acronym of ‘Jump if Above’. Each jump condition is preceded by a cmp function.
First cmp compare the two operands and returns the status, i.e. first operand is equal to
second operand (ZF = 1 and CF = 0), first operand is less than the second operand (ZF
= 1 and CF = 1) or first operand is greater than the second operand (ZF = 0 and CF =
0). According to this result, jump function is executed.
✞
1 #include <stdio.h>
3 int main () {
int out;
5 __asm__ ("movl $1 , %% eax;" /*AX = 1 */
"movl $10 , %% ebx;" /*BX = 10*/
7 "movl $15 , %% ecx;" /*CX = 15*/
"A : ;" /* Loop offset*/
9 "inc %% eax;" /*AX = AX + 1*/
"addl %%ebx , %% ecx;"/*CX = CX + BX*/
11 "cmp %%eax , %% ebx;" /*ZF = CF = 0, if AX > BX*/
"ja A;" /* Jump to Offset */
13 : "=c" (out)
);
15 printf("Output is %d", out);
return 0;
17 }
✌
✆
✞
Output is 105
✌
✆
Jump to Address
jmp unconditionally transfers control to the target location. The destination address can
be specified directly within the instruction or indirectly through a register or memory,
the acceptable size of this address depends on whether the jump is near or far (it can be
specified by preceding the operand with near or far operator) and whether the instruction
is 16-bit or 32-bit.
✞
1 #include <stdio.h>
3 int main () {
int outa , outb , outc ;
5 __asm__ ("movl $1 , %% eax;" /*AX = 1 */
"movl $10 , %% ebx;" /*BX = 10*/
7 "movl $15 , %% ecx;" /*CX = 15*/
"jmp HERE ;" /* Jump to Offset HERE */
9 "inc %% eax;" /*AX = AX + 1*/
"addl %%ebx , %% ecx;"/*CX = CX + BX*/
11 "cmp %%eax , %% ebx;" /*ZF = CF = 0, if AX > BX*/
"HERE : ;" /* Location offset*/
13 : "=a" (outa ), "=b" (outb ), "=c" (outc )
);
1.6. INSTRUCTIONS 21
15 printf("AX , BX and CX are %d, %d and %d", outa , outb , outc );
return 0;
17 }
✌
✆
✞
AX , BX and CX are 1, 10 and 15
✌
✆
As there is jump, hence inc, addl and cmp instructions are not executed and the initial
values of registers are obtained.
Store Data
movb instruction is used to store a byte in a register and movl instruction is used to
store a long data value into a register. movb is always followed by one byte long register
represented like ‘%al’ or ‘%ah’. movw is used to store 16 bits long data in 16 bits
register, like ‘%ax’ register. Note that ‘%ax’ is two byte long data whose lower 8 bits are
represented by ‘%al’ register and upper 8 bits are represented by ‘%ah’ register. movl is
used to store extra long data, i.e. 32 bits long data. This instruction is followed by 32
bits register represented like ‘%eax’, ‘%ebx’ etc.
✞
1 #include <stdio.h>
3 int main () {
int in = 10, out;
5 /* Operator input , destination */
__asm__ ("movl %1, %% eax;"
7 : "=r" (out)/* output */
: "r" (in) /* input */
9 : "%eax" /* clobbered register */
);
11 printf("out is %d", out);
return 0;
13 }
✌
✆
✞
out is 10
✌
✆
Negative of Number
It converts a number into negative number. If operand value is 10 then this instruction
makes the number −10.
✞
1 #include <stdio.h>
3 int main () {
int out;
5 __asm__ ("movl $10 , %% eax;"
"neg %% eax;"
7 : "=a" (out)
);
22 ASM in C
9 printf("Negative of 10 is %d", out);
return 0;
11 }
✌
✆
✞
Negative of 10 is -10
✌
✆
Bitwise Not
not is short name of Bitwise NOT. It inverts the bits of a binary number.
✞
1 0010 0101 : X=37
---------------- OR
3 1101 1010 : 218
✌
✆
NOT of a number, n, is computed either by inverting the binary bits or by using (−(n+1))
rule. See the example given below:
✞
1 #include <stdio.h>
3 int main () {
int out;
5 __asm__ ("movl $37 , %% eax;"
"not %% eax;"
7 : "=a" (out)
);
9 printf("NOT of 37 is %d", out);
return 0;
11 }
✌
✆
✞
NOT of 37 is -38
✌
✆
Bitwise OR
OR is short name of Bitwise OR. The output is 1 if either of the two operands or both
operands are 1 and 0 otherwise.
✞
1 0010 0101 : X=37
0101 0010 : Y=82
3 ---------------- OR
0111 0111 : 119
✌
✆
See the example given below:
✞
#include <stdio.h>
2
int main () {
4 int out;
__asm__ ("movl $37 , %% eax;"
1.6. INSTRUCTIONS 23
6 "movl $82 , %% ebx;"
"or %%eax , %% ebx;"
8 : "=b" (out)
);
10 printf("OR of 37 and 82 is %d", out);
return 0;
12 }
✌
✆
✞
OR of 37 and 82 is 119
✌
✆
The ORed result of two operands is stored in second register, i.e. in ebx register.
Rotate Bits Left Through Carry
rcl is short name of ‘Rotate Bits Left Through Carry’. It rotate the byte, word or double
word destination operand left by the number of bits specified in the second operand. rcl
additionally puts in CF each high order bit that exits from the left side of the operand
before it returns to the operand as the low order bit on the next rotation cycle.
✞
1 #include <stdio.h>
3 int main () {
int out;
5 __asm__ ("movl $10 , %% eax;"
"rcl %% eax;"
7 : "=a" (out)
);
9 printf("RCL of 10 is %d", out);
return 0;
11 }
✌
✆
✞
RCL of 10 is 20
✌
✆
Rotate Bits Right Through Carry
rcl is short name of ‘Rotate Bits Right Through Carry’. It rotate the byte, word or double
word destination operand right by the number of bits specified in the second operand.
For each rotation, rcr additionally puts in CF each low order bit that exits from the right
side of the operand before it returns to the operand as the high order bit on the next
rotation cycle.
✞
1 #include <stdio.h>
3 int main () {
int out;
5 __asm__ ("movl $10 , %% eax;"
"rcr %% eax;"
7 : "=a" (out)
24 ASM in C
);
9 printf("RCR of 10 is %d", out);
return 0;
11 }
✌
✆
✞
RCR of 10 is 5
✌
✆
Rotate to Left
rol rotate the byte, word or double word destination operand left by the number of bits
specified in the second operand. For each rotation specified, the high order bit that exits
from the left of the operand returns at the right to become the new low order bit.
✞
1 org 100h
; 254 -> 1111 1110
3 mov ax , 254 ; Initial value of AX
; ROL 254 by 1 bit left -> 1111 1101
5 ; It is equal to decimal 252 or FC hex
rol ax , 1 ; Binary left shift by one bit
7 ret
✌
✆
Above assembly language is translated into C program as given below:
✞
1 #include <stdio.h>
3 int main () {
int out;
5 __asm__ (
"movl $254 , %% ebx;"
7 "rol %% ebx;"
: "=b" (out)
9 );
printf("ROL of 254 is %d", (out & 256) );
11 return 0;
}
✌
✆
✞
ROL of 254 is 252
✌
✆
Another example similar to above program is given below:
✞
1 #include <stdio.h>
3 int main () {
int out;
5 __asm__ (
"movl $254 , %% ebx;"
7 "rol %% ebx;"
"rol %% ebx;"
9 : "=b" (out)
1.6. INSTRUCTIONS 25
);
11 printf("Twice ROL of 254 is %d", (out & 256) );
return 0;
13 }
✌
✆
✞
Twice ROL of 254 is 248
✌
✆
Rotate to Right
rorrotate the byte, word or double word destination operand right by the number of bits
specified in the second operand. For each rotation specified, the low order bit that exits
from the right of the operand returns at the left to become the new high order bit.
✞
1 org 100h
; 254 -> 1111 1110
3 mov ax , 254 ; Initial value of AX
; ROR 254 by 1 bit right -> 0111 1111
5 ; It is equal to decimal 127 or 7F hex
ror ax , 1 ; Binary left shift by one bit
7 ret
✌
✆
✞
1 #include <stdio.h>
3 int main () {
int out;
5 __asm__ (
"movl $254 , %% ebx;"
7 "ror %% ebx;"
: "=b" (out)
9 );
printf("ROR of 254 is %d", out);
11 return 0;
}
✌
✆
✞
ROR of 254 is 127
✌
✆
Set Carry Flag
It sets carry flat to high. In the following example, carry flag is set to high. Thus a jump
is take place to ‘HERE’ offset. This skips the increment of eax register. So the final
output is −10.
✞
1 #include <stdio.h>
3 int main () {
int out;
5 __asm__ ("movl $10 , %% eax;"
26 ASM in C
"stc;" /* Set carry flag .*/
7 "jc HERE ;" /* Jump to HERE .*/
"inc %% eax;" /* Skipped.*/
9 "HERE : ;"
"neg %% eax;" /* Executed */
11 : "=a" (out)
);
13 printf("Negative of 10 is %d", out);
return 0;
15 }
✌
✆
✞
Negative of 10 is -10
✌
✆
In the above example, clc instruction is placed just below to stc instruction. It skips the
jump on carry and inc instruction is executed. Now the final value is −11.
✞
1 #include <stdio.h>
3 int main () {
int out;
5 __asm__ ("movl $10 , %% eax;"
"stc;" /* Set carry flag .*/
7 "clc;" /* Clear carry flag .*/
"jc HERE ;" /* No jump to HERE */
9 "inc %% eax;" /* Executed */
"HERE : ;"
11 "neg %% eax;" /* Executed */
: "=a" (out)
13 );
printf("Negative of 10 is %d", out);
15 return 0;
}
✌
✆
✞
Negative of 10 is -11
✌
✆
Subtract
sub instruction subtracts the contents of two operands and stores the sum in first operands,
i.e. register. See the example below:
✞
1 #include <stdio.h>
3 int main () {
int in1 = 10, in2 = 15, out;
5 __asm__ ("movl %1, %% eax;"
"sub %%eax , %2;" /* Operator , register , input*/
7 : "=r" (out) /* Output */
: "r" (in2), "r" (in1) /* Two input */
9 : "%eax" /* Clobbered register */
1.6. INSTRUCTIONS 27
);
11 printf("out is %d", out);
return 0;
13 }
✌
✆
✞
out is -5
✌
✆
Bitwise Exclusive OR
XOR is short name of Bitwise Exclusive OR. The output is 1 if either of the two operands
are 1 and is 0 if both operands are 1 or 0.
✞
1 0010 0101 : X=37
0101 0010 : Y=82
3 ---------------- XOR
0111 0111 : 119
✌
✆
See the example given below:
✞
#include <stdio.h>
2
int main () {
4 int out;
__asm__ ("movl $37 , %% eax;"
6 "movl $82 , %% ebx;"
"xor %%eax , %% ebx;"
8 : "=b" (out)
);
10 printf("XOR of 37 and 82 is %d", out);
return 0;
12 }
✌
✆
✞
XOR of 37 and 82 is 119
✌
✆
28 C in ASM
2.1. NASM 29
2C in ASM
C and Assembly Languages can be used together to provide extra flexibility in programs
specially in embedded systems. Here, libraries are created in one language and they are
assessed from other languages. For correct linking, object files are created from .asm or
from .c program codes and then they are called from other programs by linking them
externally. Here, NASM assembler in linux OS is used to write libraries in assembly
language. Note that, NASM uses different code structures and symbols in different OS.
This is why, first we look into basic of NASM.
2.1 NASM
The simplest and minimal command required to compile an assembly file into executable
file is given below:
✞
1 nasm -f <format > <input file > -o <output file >
✌
✆
NASM is case sensitive compiler, for example, ‘HERE’, ‘Here’ and ‘here’ are three different
labels for NASM. NASM uses following flags during the execution of nasm.
-o This flag is used to force NASM to produce output file whose name is supplied just
after this flag. If this flag is not used, then default file name is accepted automatically by
nasm.
-f This flag is used to force the NASM to compile assembly file into format file. If
this flag is not provided, NASM selects file format automatically, i.e. binary file format.
The accepted formats are elf, bin. Other accepted file format shall be listed by using -hf
flag.
-i This flag is used to make a directory searchable to include file at the path followed
by this flag. The path name should be windows or Linux compatible.
-l This flag is used to generate a source-listing file.
-M This flag generates makefile dependencies. Flag -MG can be used to generate
makefile dependencies on stdout. This differs from the -M option in that if a non-existing
file is encountered, it is assumed to be a generated file and is added to the dependency
list without a prefix. Note that, in Windows OS, an assembly file is complied as
✞
1 nasm -fwin32 <file.asm >
gcc <file.obj >
✌
✆
while in Linux OS, it is compiled as
✞
nasm -felf <file.asm >
2 gcc <file.o >
✌
✆
30 C in ASM
One more thing, in Windows OS and with NASM, a function is always prefixed with
a underscore, while in Linux OS, leading underscores from function name should be
removed.
2.1.1 Memory Reference
NASM was designed with simplicity of syntax in mind. One of the design goals of NASM
is that it should be possible, as far as is practical. NASM have a much simpler syntax
for memory references. The rule is simply that any access to the contents of a memory
location requires square brackets around the address, and any access to the address of a
variable doesnt. So an instruction of the form
✞
mov ax ,foo
✌
✆
always refer to a compiletime constant, whether its an EQU or the address of a variable.
To access the contents of the variable ‘foo’, you must code
✞
1 mov ax ,[ foo]
✌
✆
NASM does not support the hybrid syntaxes like
✞
1 mov ax ,foo[bx]
✌
✆
The correct syntax for the above is
✞
1 mov ax ,[ foo+bx]
✌
✆
2.1.2 Defining Constants
EQU defines a symbol to a given constant value. The action of EQU is to define the
given label name to the value of its (only) operand. This definition is absolute, and
cannot change later. See the example,
✞
1 myMsg db ’hello , world’
myMsgLen equ $ m y M s g
✌
✆
defines ‘myMsgLen’ to be the constant 12. ‘myMsgLen’ may not then be redefined later.
The value of ‘myMsgLen’ is evaluated once, using the value of ‘$’ at the point of definition,
rather than being evaluated wherever it is referenced and using the value of ‘$’ at the
point of reference.
2.1.3 Character Strings
A character string consists of up to eight characters enclosed in either single quotes (‘...’),
double quotes (“...”) or backquotes (‘...‘). Strings enclosed in backquotes support Cstyle
escapes for special characters, like  single quote (), " double quote (”) etc. Unicode
characters specified with u or U are converted to UTF8.
2.1. NASM 31
2.1.4 Local Label
NASM gives special treatment to symbols beginning with a period, i.e. (.). A label
beginning with a single period (.) is treated as a local label, which means that it is
associated with the previous nonlocal label suffixed with colon (:) or not. So, for example:
✞
label1: ; some code
2 .loop
; some more code
4 jne .loop
ret
6 label2: ; some code
.loop
8 ; some more code
jne .loop
10 ret
✌
✆
In the above code fragment, each JNE instruction jumps to the line immediately before
it, because the two definitions of .loop are kept separate by virtue of each being associated
with the previous nonlocal label. If there is need to jump specific local label then it should
be write as to, you could write
✞
label1: ; a n o n l o c a l label
2 .loop
; some more code
4 jne .loop
ret
6 label2: ; another n o n l o c a l label
.loop
8 ; some more code
jne .loop
10 jmp label1.loop
ret
✌
✆
NASM has the capacity to define other special symbols beginning with a double period,
i.e. (..). for example, ..start is used to specify the entry point in the obj output format.
So just keep in mind that symbols beginning with a double period (..) are special.
✞
1 label: ; a n o n l o c a l label
..@loop
3 ; some more code
jmp ..@loop
5 ret
✌
✆
2.1.5 Local Variable
When we enter into a into a function or subroutine, compiler pushes the address of the
function/subroutine and its all arguments (in case of C program) into the stack pointer
where control is to be returned (by using ret instruction) after successful execution of
function/subroutine. After entering into a function, if function has local variables (if
32 C in ASM
any), then there is need for reserve space for these local variables. We have to make space
for local variables by decrementing the stack pointer using sub instruction. Consider a C
function
✞
1 int myExp(int i, int j) {
int a, b, c; // Three local variables
3 b = 7; /* Local variable required *
*to store value for b */
5 return i * b + j;
}
✌
✆
The stock pointer of the function shall be looked like
esp
esp-4
esp-8
rAddr of myExp
Addr of i
Addr of j
High
to
Low
Here, ‘rAddr’ is abbreviation of ‘return address’. As the function has three local
variables ‘a’, ‘b’ and ‘c’ and their address are need to store in stock pointer so that we
can track and retrieve values of these local variables. For this we can either use to sub
keyword to make space for these three local variables. See the assembly translated to
above C function is given below:
✞
myExp:
2 sub esp , 12 ; makes room for 3 ints
mov dword [esp+4], 7 ; b = 7
4 mov eax , [esp +16] ; i
imul eax , [esp +4] ; i * b
6 add eax , [esp +20] ; i * b + j
ret
✌
✆
The stock pointer of the function shall be looked like
esp
esp-4
esp-8
esp-12
esp-16
esp-20
Addr of a
Addr of b
Addr of c
rAddr of myExp
Addr of i
Addr of j
High
to
Low
2.1. NASM 33
But sometimes it is a possible to track the offsets of your parameters and local vari-
ables because the stack pointer keeps changing. Mostly within the nested functions or
subroutines. For example
✞
1 int myExp(int i, int j) {
int a, b, c; // Three local variables
3
myFunc(i, a, b, c, j);
5
}
✌
✆
Here, ‘myExp’ function pushes the addresses for itself and variables ‘i’ and ‘j’ into the
stack pointer. Now stack pointer is pushes lower to store values for three local variables
‘a’, ‘b’ and ‘c’ by using sub instruction. When subroutine for ‘myFunc’ is translated,
again address of ‘myFunc’ and five variables are pushed (by using push instruction) into
the stack pointer. Now the final stack pointer structure is looked like
esp
esp-4
esp-8
esp-12
esp-16
esp-20
esp-24
esp-28
esp-32
esp-36
esp-40
esp-44
Addr of a
Addr of b
Addr of c
rAddr of myExp
Addr of i
Addr of j
rAddr of myFunc
Addr of i
Addr of a
Addr of b
Addr of c
Addr of j
High
to
Low
Memory
Here, values of all variables are pushed at different memory address in duplicate. Due
to this, many functions use the ‘EBP’ register to index the “stack frame” of local variables
and parameters, like this:
✞
push ebp ; Must save old ebp
2 mov ebp , esp ; point ebp to this frame
sub esp , <n> ; make spaces for n local variables
4 <your codes here >
mov esp , ebp ; clean up locals
6 pop ebp ; restore old ebp
ret
✌
✆
As long as we never change ‘EBP’ in the function, all local variables and parameters will
always be at the same offset from ‘EBP’. The stack frame for this example is looked like
34 C in ASM
ebp+12
ebp+8
ebp+4
ebp
ebp-4
ebp-8
ebp-12
Addr of a
Addr of b
Addr of c
Addr of old EBP
rAddr of myFunc
Addr of i
Addr of j
High
to
Low
Memory
To be familiar with stack/base pointer, see the following C examples and the stack
pointers for C functions as given below:
✞
1 #include <stdio.h>
int ArrSum(unsigned len , int arr []);
3 int main (void ){
int nums [4], sum , n=4;
5 sum = ArrSum(n, nums );
return 0;
7 }
✌
✆
The stock/base pointer of the function ‘myArrSum’ shall be looked like
ebp
ebp-4
ebp-8
ebp-12
Addr of old EBP
rAddr of ArrSum
Addr of n
Addr of nums
esp
esp-4
esp-8
rAddr of ArrSum
Addr of n
Addr of nums
High
to
Low
When a program is called from commandline, then its stack/base pointer is looked
like as given below:
✞
1 #include <stdio.h>
int main (int argc , char ** argv ){
3 }
--> ./ myProg "a" 45
✌
✆
The stock/base pointer of the function ‘myArrSum’ shall be looked like
ebp
ebp-4
ebp-8
ebp-12
Addr of old EBP
rAddr of myProg
Addr of argc
Addr of argv
esp
esp-4
esp-8
rAddr of myProg
Addr of argc
Addr of argv
High
to
Low
2.1. NASM 35
2.1.6 Repeat
The TIMES prefix causes the instruction to be assembled multiple times. The argument
to TIMES is not just a numeric constant, but a numeric expression, so you can do things
like
✞
buff : db ’hello , world’
2 times 64 $ +buff db ’ ’
✌
✆
which will store exactly enough spaces to make the total length of buffer up to 64. The
operand to TIMES is a critical expression and it can’t be applied to macros. Its reason
is that TIMES is processed after the macro phase, which allows the argument to TIMES
to contain expressions.
2.1.7 Directives
Extern extern is similar to the C keyword extern that is used to declare a symbol
which in some other modules and needed by the current module. The extern directive
may takes one or more arguments separated with comma.
✞
extern printf
2 extern printf , scanf
✌
✆
If a variable is declared both global and extern, or as extern then it will be treated as
global. If a variable is declared both as common and extern, it will be treated as common.
Global global keyword is used to declare program location from where the program
begins to execute.
✞
global main
2 main :
<codes >
✌
✆
Global like extern allows object formats to define private extensions by means of a colon.
The elf object format lets specify whether global data items are functions or data. Global
takes only one argument at a time.
Common It defines common data area. It is used to declare common variables. A
common variable is much like a global variable declared in the uninitialized data section.
The difference is that if more than one module defines the same common variable, then
at link time those variables will be merged, and references to common variable in all
modules will point at the same piece of memory.
Static It refers to the references for local symbols within the modules. This key-
word/directive marks a variable as local symbol. Unlike global, static does not allow
object formats to accept private extensions.
Org org directive is to specify the origin address which NASM will assume the program
begins at when it is loaded into memory.
36 C in ASM
✞
1 org 0x100
dd label
3 label:
<codes >
✌
✆
org 0x100 NASM’s org directive says origin. Its sole function is to specify one offset which
is added to all internal address references within the section.
2.1.8 NASM File Layout
The simplest structure of NASM file layout is appeared as
✞
<label >: <instruction operands > ; <comment >
✌
✆
These fields are optional. They may be present or not in a NASM assembly file. NASM
uses backslash () as the line continuation character. It does not place restrictions on
white space within a line. A label may have white space before them, or instructions may
have no space before them, or anything. The colon after a label is also optional. Valid
characters in labels are letters, numbers, ‘ ’, ‘$’, ‘#’, ‘@’, ‘˜
’, ‘.’, and ‘?’. Labels must
be started with letters, dots (.), ‘ ’ and ‘?’. If an identifier is prefixed with a ‘$’ then it
indicate that it is an identifier not a reserved word. Maximum length of an identifier is
4095 characters. We can also use the name of a segment register as an instruction prefix:
✞
1 es mov [bx],ax ; both are equal
mov [es:bx],ax ; both are equal & it is recommended
✌
✆
Unlike GAS assembler, register name e.g. eax, ebp, ebx, cr0 are not prefixed by a %
sign. The Unix object formats, and the bin object format, all support the standardized
section names .text, .data and .bss for the code, data and uninitializeddata sections. The
A NASM file is divided in following sections.
✞
org 100h
2 section .text
start:
4 ; put your code here
section .data
6 ; put data items here
section .bss
8 ; put uninitialized data here
✌
✆
This file is compiled with following NASM command.
✞
nasm <.asm file > f b i n o <out file name >
✌
✆
A simple helloworld.asm program for Window OS is given below:
✞
1 section .data
msg db ’Hello World!’, 0Ah ; End with line feed character
3
section .text
2.1. NASM 37
5 global _start ; Entry point in Windows OS
7 _start: ; Window OS convention
mov edx , 13 ; Number of bytes to write
9 mov ecx , msg ; Copy msg memory address into ecx
mov ebx , 1 ; Write to the STDOUT file
11 mov eax , 4 ; invoke SYS_WRITE (kernel opcode 4)
int 80h
13 mov ebx , 0 ; return 0 on exit - ’No Errors ’
mov eax , 1 ; invoke SYS_EXIT (kernel opcode 1)
15 int 80h
✌
✆
In Linux system, underscore before labels is removed. Compile this file in NASM with
Windows OS using following command and run to see desired result.
✞
1 nasm -f elf helloworld .asm
ld -m elf_i386 helloworld .o -o helloworld
3 ./ helloworld
✌
✆
The output is
✞
Hello World!
✌
✆
2.1.9 Calling External Functions
Sometime assembly language functions are linked with C to call C functions from assembly
codes. To do so, we should have familiar with gcc calling conventions. In assembly
language, parameters are pushed on the stack, right ot left and are removed by the caller
after the call. After the parameters are pushed, the call instruction is made, so when
the called function gets control, the return address is at [esp], the first parameter is at
[esp+4], etc. It is the caller’s responsibility to remove the parameters from the stack after
a function call in stdcall or cdecl calling conventions.
rAdd of old esp (0xff00ff00) Addr of para (0xffeeff00) rAdd of printf (0xfbabff00)
esp
esp+4
Stack
High Memory Low Memory
Values of registers ebx, esi, edi, ebp, ds, es, ss, must be saved before the calling of the
function. A function that returns an integer value should return it in eax and a floating
point value should be returned on the fpu stack top. push instruction adds the value in
stack from high memory to low memory, i.e. in reverse memory order. See the following
codes.
✞
1 global main
extern printf
3 section .text
38 C in ASM
main :
5 push msg
call printf ; Calling C printf function
7 add esp , 4 ; Set the location of esp to its
; old location
9 ret
msg:
11 db ’Hello , World’, 10, 0
✌
✆
When the program being executed and on execution of each opcode, stack pointer is
incrases by one. Assume, when subroutine main was being executed, esp pointed to
memory containing the return address from subroutine. Let it is current location of esp
and it is shown in the following figure.
rAdd of old esp (0xff00ff00)
esp
Stack
High Memory Low Memory
At the execution of instruction
✞
1 push msg
✌
✆
message is stored in the memory and address of first character of the message string is
stored in the stack. Now, esp pointed to the current location of stack, which is at next
four bytes (i.e. [esp+4]) for 32 bits system. In 32 bits system, 4 bytes are sufficient to
address all possible memory locations.
rAdd of old esp (0xff00ff00) Add of msg (0xffeeff00)
esp
Stack
High Memory Low Memory
On execution of
✞
1 call printf
✌
✆
return address of printf is stored in the stack and esp pointed to this current stack
location.
rAdd of old esp (0xff00ff00) Add of msg (0xffeeff00) rAdd of printf (0xffeeffdd)
esp
Stack
High Memory Low Memory
2.1. NASM 39
While execution of printf, it moves backward (i.e. esp is decremented) in stack and
accepts required number of values from the memory addressed by the esp and gives desired
result. Due to call of printf current location of esp is changed as shown below:
rAdd of old esp (0xff00ff00) Add of msg (0xffeeff00) rAdd of printf (0xffeeffdd)
esp
Stack
High Memory Low Memory
Now, the actual position of the esp is changed, so to put the esp at its original location
on the stack, we increase the esp by equal number of bytes it was decremented and here,
it is 4 bytes (i.e. increase the location of esp from low memory to high memory). So,
instruction
✞
1 add esp , 4
✌
✆
sets the esp to its old location on the stack. Note that, when element is added in stack,
position of esp changes from high memory to low memory. This is why, to set the esp at
its old position, esp is moved towards higher memory by adding suitable number of bytes
as shown in the following figure.
rAdd of old esp (0xff00ff00) Add of msg (0xffeeff00) rAdd of printf (0xffeeffdd)
esp+4
Stack
High Memory Low Memory
Now at last, ret instruction is executed. After execution of ret control is return to
original subroutine. Stack values remain in stack and they can be accessed by changing
position of esp suitably. And current memory is set as current location of esp.
rAdd of old esp (0xff00ff00) Add of msg (0xffeeff00) rAdd of printf (0xffeeffdd)
esp
Stack
High Memory Low Memory
Compile it with following commands and run. You will get desired result.
✞
1 nasm -felf a.asm
gcc a.o -o a
3 ./a
✌
✆
40 C in ASM
esp
esp-4
rAddr of old esp
Addr of msg espPtr
rAddr of old esp
Addr of msg
rAddr of printf
High
to
Low
In above figure, the stack memory is shown before calling of printf (left) and position of
esp pointer after calling of printf (right). To put the esp i.e. stack pointer at the top of
stack, it should be incremented by 4 bytes. And it is done by add instruction as shown
in the above example. To show that stack values are not removed when we change the
location of esp, see the following example.
✞
1 global main
extern printf
3 section .text
main :
5 push msg
call printf ; Calling C printf function
7 add esp , 4 ; Set the location of esp to its
; old location
9 sub esp , 4 ; Set esp to location of msg address
call printf ; Calling C printf function
11 add esp , 4 ; Set the location of esp to its
; old location
13 ret
msg:
15 db ’Hello , World’, 10, 0
✌
✆
When compiled and run, we will find the desired result.
✞
Hello , World
Hello , World
✌
✆
In case of return of numeric value, the above code shall be modifed accordingly.
✞
global main
2 extern printf
section .text
4 main :
mov ecx , 40 ; Original value to ecx
6 push ecx ; Store original value
;sequencial stack values for printf
8 push ecx ;L1 Copy printing value in stack
push format ;L2 Copy printf format in stack
10 call printf ;L3 Call printf function of C
;
12 add esp , 8 ; Set esp at esp+8 location from
; current esp pointer location and
14 ; remove all elements at low memory side
pop ecx ; Restore value of ecx
16 ret
2.1. NASM 41
format:
18 db ’%10d’, 0
✌
✆
in above example, two parameters are pushed into the stack. First is value to be printed
(L1), second is format (L2) and then printf is called (L3), which is equivalent to
✞
printf("%10d",<ecx >);
✌
✆
At call of printf function, required format and values being started reading backward
through stack addresses. After reading required parameters, printf is executed, result is
stored in memory and its address is pushed at the top of the stack.
esp
esp-4
esp-8
esp-12
rAddr of old esp
Addr of value 40
Addr of value 40
Addr of format
espPtr
rAddr of old esp
Addr of value 40
Addr of value 40
Addr of format
rAddr of printf
High
to
Low
Memory
In above figure, the stack memory is shown before calling of printf (left) and position
of esp pointer after calling of printf (right). To put the esp i.e. stack pointer at the top
of stack, it should be incremented by 8 bytes. And it is done by add instruction as shown
in the above example. There is also interrupt mode of printing string in the console. See
the following example.
✞
1 section .data
str: db "Hello , how are you? ", 100, 0
3
section .text
5
global main
7
main :
9 mov eax , 4 ; EAX=4 & EBX=1 (SYS_WRITE kernel mode )
mov ebx , 1 ; write to STDOUT file
11 mov ecx , str ; string at destination
mov edx , 100 ; Length of string
13 int 80h ; interrupt
15 mov eax , 1 ; Return
mov ebx , 0 ; Return code
17 int 80h ; interrupt
✌
✆
2.1.10 Uers’s Input
In Linux Kernel, the combination of eax and ebx register allow read and write of the data
from the stream or into the stream respectively. For example, setting eax as 3 and ebx
42 C in ASM
as 0 results System Read Kernel Mode and system reades data from the input stream.
Similarly, setting eas as 4 and ebx as 1 results System Write Kernel Mode and system
writes data into the output stream. See the example below:
✞
1 section .data
str: db 100 ; Allocate buffer of 100 bytes
3
section .text
5
global main
7
main :
9 mov eax , 3 ; EAX=3 & EBX=0 (SYS_READ kernel mode )
mov ebx , 0 ; write to STDIN file
11 mov ecx , str ; copy string at destination
mov edx , 100 ; Length of string
13 int 80h ; interrupt to end 
15 mov eax , 4 ; EAX=4 & EBX=1 (SYS_WRITE kernel mode )
mov ebx , 1 ; write to STDOUT file
17 mov ecx , str ; string at destination
mov edx , 100 ; Length of string
19 int 80h ; interrupt to end 
21 mov eax , 1 ; Return
mov ebx , 0 ; Return code
23 int 80h ; interrupt to end 
✌
✆
2.1.11 Macros
Assemblers are line oriented, i.e. they codes line-by-line. This is why, NASM has single
line macros as well as multiline macros. In NASM, single line macros are declared with
define keyword as given below:
✞
1 %define myVar mov
✌
✆
Here, ‘myVar’ is macro name and mov is its value. See the example below, in which ‘msg’
label is redefined to ‘mymsg’ by using %define directive.
✞
1 global main
extern printf
3 section .text
%define mymsg msg
5 main :
push mymsg
7 call printf ; calling C printf function
add esp , 4 ; Set the location of esp to
9 ; its old location and remove
; all stack elements at low
11 ; memory side
2.1. NASM 43
ret
13 msg:
db ’Hello , World’, 10, 0
✌
✆
Multi-line NASM macros are declared as given below:
✞
%macro <macro name > <n>
2 <codes >
%endmacro
✌
✆
Here, ‘n’ is number of possible arguments those shall be passed to this macro. Macroname
may or may not be reserved keywords. Arguments may be zero or more than one. In
case of more than one parameters, each sequential parameters are passed to placeholder
by %1, %2 etc. Multi-line macros, like single-line macros, are case-sensitive, unless you
define them using the alternative directive %imacro. Macro names may or may not a
machine instruction. In case of macro name is machine instruction, then it will overload
to the previously defined macro.
✞
1 extern printf
%macro myMacro 1 ; user ’s print macro
3 section .data
mystr db %1,0 ; %1 is first parameter in macro call
5 section .text
; pushed onto stack backwards
7 push dword [c] ; int c
push dword [b] ; int b
9 push dword [a] ; int a
push dword mystr ; users string
11 push dword fmt ; address of format string
call printf ; Call C function
13 add esp ,20 ; Set esp at its old location
; and remove elements at low
15 ; memory side
%endmacro
17
section .data ; preset constants , writeable
19 fmt: db "%s, a=%d, b=%d, c=%d" ,10,0
a: dd 5
21 b: dd 6
c: dd 0
23
section .text ; instructions , code segment
25 global main ; gcc standard linking label
main : ; gcc entry point -> "main "
27 mov eax ,[a] ; load a
add eax ,[b] ; add b
29 mov [c],eax ; copy a+b into c
myMacro "c=a+b" ; call user ’s printing macro
31
mov eax ,0 ; exit code , 0= normal
33 ret ; main return to operating system
✌
✆
44 C in ASM
Compile it with following commands and run. You will get desired result.
✞
1 nasm -felf a.asm
gcc a.o -o a
3 ./a
✌
✆
The output of above code is
✞
c+a+b, a=5, b=6, c=11
✌
✆
NASM allows to define labels within a multi-line macro definition in such a way as to
make them local to the macro call. To do this, label is prefixed by %%. See the structure
as given below:
✞
1 %macro myMacro 0
jnz %% mySkip
3 ret
%% mySkip:
5 %endmacro
✌
✆
Every time we call this macro, NASM make up a different ‘real’ name to substitute for
the label%%mySkip. Label names should not be started with ‘@’ as it is used by NASM
to declared macro-local lebels by own. Sometime, a macro is passed comma separated
string whose one or two comma separated strings from the front are parameters and rest
are data string. At this case, greedy macro is more useful.
✞
1 %macro myMacro 2+
%% str: db %2
3 %% endstr:
mov dx ,%% str
5 mov bx ,%1
%endmacro
✌
✆
Here, ‘2+’ represents two arguments to this macro in which second is expanded greedy
macro. In NASM greedy macro is indicated by ‘+’ sign after the parameter count on the
macro line. When this macro is called with following command
✞
myMacro 10,"my string" ,120,52
✌
✆
Then ‘%1’ placeholder shall be assigned only value 10 and rest of the string is placed at
the placeholder ‘%2’.
✞
1 extern printf
%macro myMacro 2+ ; user ’s greedy print macro
3 section .data
myFstr db %1,0 ; %1 is first parameter
5 mySstr db %2,0 ; %2 is rest of parameters
section .text
7 ; pushed onto stack backwards
push mySstr ; rest of string
9 push myFstr ; first string
2.1. NASM 45
push dword fmt ; address of format string
11 call printf ; Call C function
add esp ,12 ; Set esp at its old location
13 ; and remove all elements at
; low memory side
15 %endmacro
section .data ; preset constants , writeable
17 fmt: db "%s, %s" ,10,0
19 section .text ; instructions , code segment
global main ; for gcc standard linking
21 main : ; label "main "
; call user ’s printing macro
23 myMacro "print","This is string No.","3"
25 mov eax ,0 ; exit code , 0= normal
ret
✌
✆
Compile it with following commands and run. You will get desired result.
✞
root@box$ nasm -felf a.asm
2 root@box$ gcc a.o -o a
root@box$ ./a
✌
✆
The output of above code is
✞
print , This is string No .3
✌
✆
NASM also allows to expand range parameters via special constructions as shown
below or example
✞
1 %macro myRange 1-*
db %{3:5} ; Arguments from 3rd to 5th parameters
3 %endmacro
✌
✆
Range values may be positive or negative values but not zero. The range is moved from
first range value to second range value either in increasing order or in decreasing order,
depends which is greater. If this macro is called with instruction
✞
1 myRange 1,2,3,4,5,6
✌
✆
Then output shall be only 3,4,5. NASM also allows to define a multi-line macro with a
range of allowable parameter counts. So, for example:
✞
1 %macro dieMacro 0-1 "Exiting due to error."
<codes >
3 %endmacro
✌
✆
If this macro is called with less number of required arguments or more then it show error
before exiting from the macro.
46 C in ASM
There are several inbuilt NASM macros which are used explicitely. They are %rotate
for rotate parameter, %if-%elif-%else. Each %if condition should be closed with %endif
macro. %ifdef is used to check whether a parameter is already defined or not and it should
be closed with %endif macro. %ifmacro is considered true if defining a macro with the
given name and number of arguments would cause a definitions conflict. %ifnum tests for
the token being a numeric constant, %ifstr tests for it being a string.
2.1.12 Executing Command
The EXEC family of functions replace the currently running process with a new process,
that executes the specified command when calling it. We will be using the SYS EXECVE
function to replace our program’s running process with a new process that will be exe-
cuted. The first argument is a string containing the command to execute, then an array
of arguments is to pass to that command and then another array of environment vari-
ables that the new process will use. Both the command arguments and the environment
arguments need to be passed as an array of pointers and then passed to SYS EXECVE.
We call the function and the process is replaced by our command and output is returned
to the terminal.
✞
1 SECTION .data
command db ’/bin/echo ’, 0h ; command to execute
3 arg1 db ’Hello World!’, 0h
arguments dd command
5 dd arg1 ; arguments to pass to commandline
dd 0h ; end the struct
7 env dd 0h ; arguments to pass as
; environment variables
9 SECTION .text
global main
11 main :
mov edx , env ; address of environment variables
13 mov ecx , arguments ; address of the arguments
; to pass to commandline
15 mov ebx , command ; address of the file to execute
mov eax , 11 ; invoke SYS_EXECVE (kernel opcode 11)
17 int 80h
✌
✆
2.2 Link ASM with C
First we shall write a .asm program which has a user defined function that shall be called
from C by linking it. See the following example, in a user defined ‘myFirstAsm’ is defined
to print string ‘Hello, world!’.
✞
1 section .data
hello: db ’Hello , world!’, 10
3
section .text
5 global myFirstASM
2.2. LINK ASM WITH C 47
7 myFirstASM :
mov eax , 4 ; Leave space on stack for
9 ; local variable "myFirstASM "
mov ebx , 1
11 mov ecx , hello
mov edx , 13
13 int 80h
ret
✌
✆
Compile above program for 32 bit executable and linkable format (elf32) by using following
command.
✞
nasm -f elf32 myFirstAsm.asm -o myFirstAsm.o
✌
✆
Write a C program using extern keyword to access the ‘myFirstASM’ function as compiled
above.
✞
1 #include <stdio.h>
3 int main (int argc , char *argv []) {
extern myFirstASM ();
5 myFirstASM ();
}
✌
✆
Now compile it with gcc using following command.
✞
gcc myFirstAsm .c myFirstAsm .o -o hello
2 ./ hello
✌
✆
you will get the desired output. ASM functions can be called with input values from C
programms too. See the following codes. The codes of add.asm file is given below:
✞
section .text
2 global myAsmAdd
myAsmAdd :
4 push ebp ; Save the prior Base Pointer value
mov ebp , esp ; Copy Stock Pointer into Base
6 ; Pointer [ebp +0] Space for old
; ebp value [ebp +4] Space for
8 ; return address
mov eax , [ebp +8] ; Base Index Addressing.
10 ; Get First Input Value
add eax , [ebp +12] ; Get Second input Value
12 pop ebp ; Return Output
ret
✌
✆
The codes of addc.c file is given below:
✞
1 #include <stdio.h>
/* Function , written in Assembly Language . */
48 C in ASM
3 int myAsmAdd (int , int);
int main (void ) {
5 int a, b, ans;
printf("Enter a, b: ");
7 scanf(" %i %i", &a, &b);
ans = myAsmAdd (a, b);
9 printf("%dn", ans);
return 0;
11 }
✌
✆
Compile above program as given commands and run them. Your shall get desired result.
✞
1 root@box$ gcc -Wall -c addc.c -o addc.o
root@box$ nasm -f coff add.asm
3 root@box$ gcc -o add addc.o add.o
root@box$ ./add
✌
✆
If there is error in compilation of assembly file, then use following command.
✞
root@box$ nasm -f elf32 add.asm
✌
✆
We can also specify the data variable names or function names written in the assembly
code and being called for a variable or for a C function by using asm (or asm ) keyword
after the declarator. We should be careful while choosing assembler names as they do not
conflict with any other assembler symbols, or reference registers.
✞
1 char *chello asm ("hello");
✌
✆
Now we can print the string assigned to “hello” in assembly code from the C codes directly
as
✞
1 #include <stdio.h>
char *chello asm ("hello");
3 int main (void ) {
printf("%s", chello);
5 return 0;
}
✌
✆
Similarly, we can specify an assembly function for C codes as
✞
#include <stdio.h>
2 /* myAsmAdd , written in Assembly Language . */
int cAdd (int , int) asm("myAsmAdd ");
4 int main (void ) {
int a, b, ans;
6 printf("Enter a, b: ");
scanf(" %i %i", &a, &b);
8 ans = cAdd (a, b);
printf("%dn", ans);
10 return 0;
}
✌
✆
2.2. LINK ASM WITH C 49
Compile above program as given commands and run them. Your shall get desired result.
✞
1 root@box$ gcc -Wall -c addc.c -o addc.o
root@box$ nasm -f elf32 add.asm
3 root@box$ gcc -o add addc.o add.o
root@box$ ./add
✌
✆

More Related Content

What's hot

Java Programming Notes for Beginners by Arun Umrao
Java Programming Notes for Beginners by Arun UmraoJava Programming Notes for Beginners by Arun Umrao
Java Programming Notes for Beginners by Arun Umraossuserd6b1fd
 
Modlica an introduction by Arun Umrao
Modlica an introduction by Arun UmraoModlica an introduction by Arun Umrao
Modlica an introduction by Arun Umraossuserd6b1fd
 
Notes for GNU Octave - Numerical Programming - for Students 01 of 02 by Arun ...
Notes for GNU Octave - Numerical Programming - for Students 01 of 02 by Arun ...Notes for GNU Octave - Numerical Programming - for Students 01 of 02 by Arun ...
Notes for GNU Octave - Numerical Programming - for Students 01 of 02 by Arun ...ssuserd6b1fd
 
Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...
Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...
Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...ssuserd6b1fd
 
Advanced cardiovascular exercites
Advanced cardiovascular exercitesAdvanced cardiovascular exercites
Advanced cardiovascular exercitesMaria Lopez
 
Tinyos programming
Tinyos programmingTinyos programming
Tinyos programmingssuserf04f61
 
Francois fleuret -_c++_lecture_notes
Francois fleuret -_c++_lecture_notesFrancois fleuret -_c++_lecture_notes
Francois fleuret -_c++_lecture_noteshamza239523
 
The C Preprocessor
The C PreprocessorThe C Preprocessor
The C Preprocessoriuui
 

What's hot (12)

Java Programming Notes for Beginners by Arun Umrao
Java Programming Notes for Beginners by Arun UmraoJava Programming Notes for Beginners by Arun Umrao
Java Programming Notes for Beginners by Arun Umrao
 
Modlica an introduction by Arun Umrao
Modlica an introduction by Arun UmraoModlica an introduction by Arun Umrao
Modlica an introduction by Arun Umrao
 
Notes for GNU Octave - Numerical Programming - for Students 01 of 02 by Arun ...
Notes for GNU Octave - Numerical Programming - for Students 01 of 02 by Arun ...Notes for GNU Octave - Numerical Programming - for Students 01 of 02 by Arun ...
Notes for GNU Octave - Numerical Programming - for Students 01 of 02 by Arun ...
 
Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...
Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...
Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...
 
Advanced cardiovascular exercites
Advanced cardiovascular exercitesAdvanced cardiovascular exercites
Advanced cardiovascular exercites
 
Tinyos programming
Tinyos programmingTinyos programming
Tinyos programming
 
Francois fleuret -_c++_lecture_notes
Francois fleuret -_c++_lecture_notesFrancois fleuret -_c++_lecture_notes
Francois fleuret -_c++_lecture_notes
 
Thats How We C
Thats How We CThats How We C
Thats How We C
 
The C Preprocessor
The C PreprocessorThe C Preprocessor
The C Preprocessor
 
Hats guia de_macro
Hats guia de_macroHats guia de_macro
Hats guia de_macro
 
Advanced macro guide
Advanced macro guideAdvanced macro guide
Advanced macro guide
 
Electrónica digital: Logicsim
Electrónica digital: LogicsimElectrónica digital: Logicsim
Electrónica digital: Logicsim
 

Similar to C & ASM AN INTRODUCTION - ASM in C and Extended ASM

Modbus protocol reference guide
Modbus protocol reference guideModbus protocol reference guide
Modbus protocol reference guidePanggih Supraja
 
8051 micro controller
8051 micro controller8051 micro controller
8051 micro controllerArun Umrao
 
Reverse engineering for_beginners-en
Reverse engineering for_beginners-enReverse engineering for_beginners-en
Reverse engineering for_beginners-enAndri Yabu
 
C++ annotations version
C++ annotations versionC++ annotations version
C++ annotations versionPL Sharma
 
system on chip for telecommand system design
system on chip for telecommand system designsystem on chip for telecommand system design
system on chip for telecommand system designRaghavendra Badager
 
S Pii Plus+C+Library+Programmer+Guide
S Pii Plus+C+Library+Programmer+GuideS Pii Plus+C+Library+Programmer+Guide
S Pii Plus+C+Library+Programmer+Guideguestd2fe1e
 
S Pii Plus+C+Library+Programmer+Guide
S Pii Plus+C+Library+Programmer+GuideS Pii Plus+C+Library+Programmer+Guide
S Pii Plus+C+Library+Programmer+Guideguestd2fe1e
 
Introduction to MATLAB Programming and Numerical Methods for Engineers 1st Ed...
Introduction to MATLAB Programming and Numerical Methods for Engineers 1st Ed...Introduction to MATLAB Programming and Numerical Methods for Engineers 1st Ed...
Introduction to MATLAB Programming and Numerical Methods for Engineers 1st Ed...AmeryWalters
 
97244898-Turbo-Assembler-Version-5-Users-Guide.pdf
97244898-Turbo-Assembler-Version-5-Users-Guide.pdf97244898-Turbo-Assembler-Version-5-Users-Guide.pdf
97244898-Turbo-Assembler-Version-5-Users-Guide.pdfkalelboss
 
Introduction to c++ (cpp)
Introduction to c++ (cpp)Introduction to c++ (cpp)
Introduction to c++ (cpp)Arun Umrao
 
Swf File Format Spec V10
Swf File Format Spec V10Swf File Format Spec V10
Swf File Format Spec V10losalamos
 
vdoc.pub_static-timing-analysis-for-nanometer-designs-a-practical-approach-.pdf
vdoc.pub_static-timing-analysis-for-nanometer-designs-a-practical-approach-.pdfvdoc.pub_static-timing-analysis-for-nanometer-designs-a-practical-approach-.pdf
vdoc.pub_static-timing-analysis-for-nanometer-designs-a-practical-approach-.pdfquandao25
 

Similar to C & ASM AN INTRODUCTION - ASM in C and Extended ASM (20)

Modbus protocol reference guide
Modbus protocol reference guideModbus protocol reference guide
Modbus protocol reference guide
 
8051 micro controller
8051 micro controller8051 micro controller
8051 micro controller
 
OPCDE Crackme Solution
OPCDE Crackme SolutionOPCDE Crackme Solution
OPCDE Crackme Solution
 
Reverse engineering for_beginners-en
Reverse engineering for_beginners-enReverse engineering for_beginners-en
Reverse engineering for_beginners-en
 
Mat power manual
Mat power manualMat power manual
Mat power manual
 
C++ annotations version
C++ annotations versionC++ annotations version
C++ annotations version
 
Notes of Java
Notes of JavaNotes of Java
Notes of Java
 
ABB PROFIBUS.
ABB   PROFIBUS.    ABB   PROFIBUS.
ABB PROFIBUS.
 
system on chip for telecommand system design
system on chip for telecommand system designsystem on chip for telecommand system design
system on chip for telecommand system design
 
Introduction to Matlab
Introduction to MatlabIntroduction to Matlab
Introduction to Matlab
 
S Pii Plus+C+Library+Programmer+Guide
S Pii Plus+C+Library+Programmer+GuideS Pii Plus+C+Library+Programmer+Guide
S Pii Plus+C+Library+Programmer+Guide
 
S Pii Plus+C+Library+Programmer+Guide
S Pii Plus+C+Library+Programmer+GuideS Pii Plus+C+Library+Programmer+Guide
S Pii Plus+C+Library+Programmer+Guide
 
Introduction to MATLAB Programming and Numerical Methods for Engineers 1st Ed...
Introduction to MATLAB Programming and Numerical Methods for Engineers 1st Ed...Introduction to MATLAB Programming and Numerical Methods for Engineers 1st Ed...
Introduction to MATLAB Programming and Numerical Methods for Engineers 1st Ed...
 
matlab_prog.pdf
matlab_prog.pdfmatlab_prog.pdf
matlab_prog.pdf
 
97244898-Turbo-Assembler-Version-5-Users-Guide.pdf
97244898-Turbo-Assembler-Version-5-Users-Guide.pdf97244898-Turbo-Assembler-Version-5-Users-Guide.pdf
97244898-Turbo-Assembler-Version-5-Users-Guide.pdf
 
Introduction to c++ (cpp)
Introduction to c++ (cpp)Introduction to c++ (cpp)
Introduction to c++ (cpp)
 
Bash
BashBash
Bash
 
Swf File Format Spec V10
Swf File Format Spec V10Swf File Format Spec V10
Swf File Format Spec V10
 
Crypto101
Crypto101Crypto101
Crypto101
 
vdoc.pub_static-timing-analysis-for-nanometer-designs-a-practical-approach-.pdf
vdoc.pub_static-timing-analysis-for-nanometer-designs-a-practical-approach-.pdfvdoc.pub_static-timing-analysis-for-nanometer-designs-a-practical-approach-.pdf
vdoc.pub_static-timing-analysis-for-nanometer-designs-a-practical-approach-.pdf
 

More from ssuserd6b1fd

Notes for c programming for mca, bca, b. tech cse, ece and msc (cs) 1 of 5 by...
Notes for c programming for mca, bca, b. tech cse, ece and msc (cs) 1 of 5 by...Notes for c programming for mca, bca, b. tech cse, ece and msc (cs) 1 of 5 by...
Notes for c programming for mca, bca, b. tech cse, ece and msc (cs) 1 of 5 by...ssuserd6b1fd
 
Decreasing increasing functions by arun umrao
Decreasing increasing functions by arun umraoDecreasing increasing functions by arun umrao
Decreasing increasing functions by arun umraossuserd6b1fd
 
Distribution of normal data understanding it numerical way by arun umrao
Distribution of normal data   understanding it numerical way by arun umraoDistribution of normal data   understanding it numerical way by arun umrao
Distribution of normal data understanding it numerical way by arun umraossuserd6b1fd
 
Decreasing and increasing functions by arun umrao
Decreasing and increasing functions by arun umraoDecreasing and increasing functions by arun umrao
Decreasing and increasing functions by arun umraossuserd6b1fd
 
What is meaning of epsilon and delta in limits of a function by Arun Umrao
What is meaning of epsilon and delta in limits of a function by Arun UmraoWhat is meaning of epsilon and delta in limits of a function by Arun Umrao
What is meaning of epsilon and delta in limits of a function by Arun Umraossuserd6b1fd
 
Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...
Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...
Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...ssuserd6b1fd
 
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...ssuserd6b1fd
 
Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...
Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...
Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...ssuserd6b1fd
 
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...ssuserd6b1fd
 
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 4 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 4 of 5 by...Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 4 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 4 of 5 by...ssuserd6b1fd
 
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 3 of 5 b...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 3 of 5  b...Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 3 of 5  b...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 3 of 5 b...ssuserd6b1fd
 
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 2 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 2 of 5 by...Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 2 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 2 of 5 by...ssuserd6b1fd
 
Work and Energy Notes by Arun Umrao
Work and Energy Notes by Arun UmraoWork and Energy Notes by Arun Umrao
Work and Energy Notes by Arun Umraossuserd6b1fd
 
Notes of Units, Dimensions & Errors for IIT JEE by Arun Umrao
Notes of Units, Dimensions & Errors for IIT JEE by Arun UmraoNotes of Units, Dimensions & Errors for IIT JEE by Arun Umrao
Notes of Units, Dimensions & Errors for IIT JEE by Arun Umraossuserd6b1fd
 
Physics dictionary for CBSE, ISCE, Class X Students by Arun Umrao
Physics dictionary for CBSE, ISCE, Class X Students by Arun UmraoPhysics dictionary for CBSE, ISCE, Class X Students by Arun Umrao
Physics dictionary for CBSE, ISCE, Class X Students by Arun Umraossuserd6b1fd
 
Maxima & Minima of Functions - Differential Calculus by Arun Umrao
Maxima & Minima of Functions - Differential Calculus by Arun UmraoMaxima & Minima of Functions - Differential Calculus by Arun Umrao
Maxima & Minima of Functions - Differential Calculus by Arun Umraossuserd6b1fd
 
Principles of Linear Motion of Objects - Physics - Explained by Arun Umrao
Principles of Linear Motion of Objects - Physics - Explained by Arun UmraoPrinciples of Linear Motion of Objects - Physics - Explained by Arun Umrao
Principles of Linear Motion of Objects - Physics - Explained by Arun Umraossuserd6b1fd
 
Limit & Continuity of Functions - Differential Calculus by Arun Umrao
Limit & Continuity of Functions - Differential Calculus by Arun UmraoLimit & Continuity of Functions - Differential Calculus by Arun Umrao
Limit & Continuity of Functions - Differential Calculus by Arun Umraossuserd6b1fd
 
Principle of Integration - Basic Introduction - by Arun Umrao
Principle of Integration - Basic Introduction - by Arun UmraoPrinciple of Integration - Basic Introduction - by Arun Umrao
Principle of Integration - Basic Introduction - by Arun Umraossuserd6b1fd
 
Principle of Integral Applications - Integral Calculus - by Arun Umrao
Principle of Integral Applications - Integral Calculus - by Arun UmraoPrinciple of Integral Applications - Integral Calculus - by Arun Umrao
Principle of Integral Applications - Integral Calculus - by Arun Umraossuserd6b1fd
 

More from ssuserd6b1fd (20)

Notes for c programming for mca, bca, b. tech cse, ece and msc (cs) 1 of 5 by...
Notes for c programming for mca, bca, b. tech cse, ece and msc (cs) 1 of 5 by...Notes for c programming for mca, bca, b. tech cse, ece and msc (cs) 1 of 5 by...
Notes for c programming for mca, bca, b. tech cse, ece and msc (cs) 1 of 5 by...
 
Decreasing increasing functions by arun umrao
Decreasing increasing functions by arun umraoDecreasing increasing functions by arun umrao
Decreasing increasing functions by arun umrao
 
Distribution of normal data understanding it numerical way by arun umrao
Distribution of normal data   understanding it numerical way by arun umraoDistribution of normal data   understanding it numerical way by arun umrao
Distribution of normal data understanding it numerical way by arun umrao
 
Decreasing and increasing functions by arun umrao
Decreasing and increasing functions by arun umraoDecreasing and increasing functions by arun umrao
Decreasing and increasing functions by arun umrao
 
What is meaning of epsilon and delta in limits of a function by Arun Umrao
What is meaning of epsilon and delta in limits of a function by Arun UmraoWhat is meaning of epsilon and delta in limits of a function by Arun Umrao
What is meaning of epsilon and delta in limits of a function by Arun Umrao
 
Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...
Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...
Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...
 
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
 
Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...
Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...
Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...
 
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...
 
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 4 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 4 of 5 by...Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 4 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 4 of 5 by...
 
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 3 of 5 b...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 3 of 5  b...Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 3 of 5  b...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 3 of 5 b...
 
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 2 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 2 of 5 by...Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 2 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 2 of 5 by...
 
Work and Energy Notes by Arun Umrao
Work and Energy Notes by Arun UmraoWork and Energy Notes by Arun Umrao
Work and Energy Notes by Arun Umrao
 
Notes of Units, Dimensions & Errors for IIT JEE by Arun Umrao
Notes of Units, Dimensions & Errors for IIT JEE by Arun UmraoNotes of Units, Dimensions & Errors for IIT JEE by Arun Umrao
Notes of Units, Dimensions & Errors for IIT JEE by Arun Umrao
 
Physics dictionary for CBSE, ISCE, Class X Students by Arun Umrao
Physics dictionary for CBSE, ISCE, Class X Students by Arun UmraoPhysics dictionary for CBSE, ISCE, Class X Students by Arun Umrao
Physics dictionary for CBSE, ISCE, Class X Students by Arun Umrao
 
Maxima & Minima of Functions - Differential Calculus by Arun Umrao
Maxima & Minima of Functions - Differential Calculus by Arun UmraoMaxima & Minima of Functions - Differential Calculus by Arun Umrao
Maxima & Minima of Functions - Differential Calculus by Arun Umrao
 
Principles of Linear Motion of Objects - Physics - Explained by Arun Umrao
Principles of Linear Motion of Objects - Physics - Explained by Arun UmraoPrinciples of Linear Motion of Objects - Physics - Explained by Arun Umrao
Principles of Linear Motion of Objects - Physics - Explained by Arun Umrao
 
Limit & Continuity of Functions - Differential Calculus by Arun Umrao
Limit & Continuity of Functions - Differential Calculus by Arun UmraoLimit & Continuity of Functions - Differential Calculus by Arun Umrao
Limit & Continuity of Functions - Differential Calculus by Arun Umrao
 
Principle of Integration - Basic Introduction - by Arun Umrao
Principle of Integration - Basic Introduction - by Arun UmraoPrinciple of Integration - Basic Introduction - by Arun Umrao
Principle of Integration - Basic Introduction - by Arun Umrao
 
Principle of Integral Applications - Integral Calculus - by Arun Umrao
Principle of Integral Applications - Integral Calculus - by Arun UmraoPrinciple of Integral Applications - Integral Calculus - by Arun Umrao
Principle of Integral Applications - Integral Calculus - by Arun Umrao
 

Recently uploaded

An experimental study in using natural admixture as an alternative for chemic...
An experimental study in using natural admixture as an alternative for chemic...An experimental study in using natural admixture as an alternative for chemic...
An experimental study in using natural admixture as an alternative for chemic...Chandu841456
 
GDSC ASEB Gen AI study jams presentation
GDSC ASEB Gen AI study jams presentationGDSC ASEB Gen AI study jams presentation
GDSC ASEB Gen AI study jams presentationGDSCAESB
 
Work Experience-Dalton Park.pptxfvvvvvvv
Work Experience-Dalton Park.pptxfvvvvvvvWork Experience-Dalton Park.pptxfvvvvvvv
Work Experience-Dalton Park.pptxfvvvvvvvLewisJB
 
Electronically Controlled suspensions system .pdf
Electronically Controlled suspensions system .pdfElectronically Controlled suspensions system .pdf
Electronically Controlled suspensions system .pdfme23b1001
 
Call Girls Narol 7397865700 Independent Call Girls
Call Girls Narol 7397865700 Independent Call GirlsCall Girls Narol 7397865700 Independent Call Girls
Call Girls Narol 7397865700 Independent Call Girlsssuser7cb4ff
 
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptxDecoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptxJoão Esperancinha
 
EduAI - E learning Platform integrated with AI
EduAI - E learning Platform integrated with AIEduAI - E learning Platform integrated with AI
EduAI - E learning Platform integrated with AIkoyaldeepu123
 
Introduction-To-Agricultural-Surveillance-Rover.pptx
Introduction-To-Agricultural-Surveillance-Rover.pptxIntroduction-To-Agricultural-Surveillance-Rover.pptx
Introduction-To-Agricultural-Surveillance-Rover.pptxk795866
 
Call Girls Delhi {Jodhpur} 9711199012 high profile service
Call Girls Delhi {Jodhpur} 9711199012 high profile serviceCall Girls Delhi {Jodhpur} 9711199012 high profile service
Call Girls Delhi {Jodhpur} 9711199012 high profile servicerehmti665
 
VICTOR MAESTRE RAMIREZ - Planetary Defender on NASA's Double Asteroid Redirec...
VICTOR MAESTRE RAMIREZ - Planetary Defender on NASA's Double Asteroid Redirec...VICTOR MAESTRE RAMIREZ - Planetary Defender on NASA's Double Asteroid Redirec...
VICTOR MAESTRE RAMIREZ - Planetary Defender on NASA's Double Asteroid Redirec...VICTOR MAESTRE RAMIREZ
 
Application of Residue Theorem to evaluate real integrations.pptx
Application of Residue Theorem to evaluate real integrations.pptxApplication of Residue Theorem to evaluate real integrations.pptx
Application of Residue Theorem to evaluate real integrations.pptx959SahilShah
 
CCS355 Neural Network & Deep Learning Unit II Notes with Question bank .pdf
CCS355 Neural Network & Deep Learning Unit II Notes with Question bank .pdfCCS355 Neural Network & Deep Learning Unit II Notes with Question bank .pdf
CCS355 Neural Network & Deep Learning Unit II Notes with Question bank .pdfAsst.prof M.Gokilavani
 
pipeline in computer architecture design
pipeline in computer architecture  designpipeline in computer architecture  design
pipeline in computer architecture designssuser87fa0c1
 
Concrete Mix Design - IS 10262-2019 - .pptx
Concrete Mix Design - IS 10262-2019 - .pptxConcrete Mix Design - IS 10262-2019 - .pptx
Concrete Mix Design - IS 10262-2019 - .pptxKartikeyaDwivedi3
 
Past, Present and Future of Generative AI
Past, Present and Future of Generative AIPast, Present and Future of Generative AI
Past, Present and Future of Generative AIabhishek36461
 
Oxy acetylene welding presentation note.
Oxy acetylene welding presentation note.Oxy acetylene welding presentation note.
Oxy acetylene welding presentation note.eptoze12
 
Heart Disease Prediction using machine learning.pptx
Heart Disease Prediction using machine learning.pptxHeart Disease Prediction using machine learning.pptx
Heart Disease Prediction using machine learning.pptxPoojaBan
 

Recently uploaded (20)

An experimental study in using natural admixture as an alternative for chemic...
An experimental study in using natural admixture as an alternative for chemic...An experimental study in using natural admixture as an alternative for chemic...
An experimental study in using natural admixture as an alternative for chemic...
 
GDSC ASEB Gen AI study jams presentation
GDSC ASEB Gen AI study jams presentationGDSC ASEB Gen AI study jams presentation
GDSC ASEB Gen AI study jams presentation
 
Work Experience-Dalton Park.pptxfvvvvvvv
Work Experience-Dalton Park.pptxfvvvvvvvWork Experience-Dalton Park.pptxfvvvvvvv
Work Experience-Dalton Park.pptxfvvvvvvv
 
Electronically Controlled suspensions system .pdf
Electronically Controlled suspensions system .pdfElectronically Controlled suspensions system .pdf
Electronically Controlled suspensions system .pdf
 
Call Girls Narol 7397865700 Independent Call Girls
Call Girls Narol 7397865700 Independent Call GirlsCall Girls Narol 7397865700 Independent Call Girls
Call Girls Narol 7397865700 Independent Call Girls
 
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptxDecoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
 
Design and analysis of solar grass cutter.pdf
Design and analysis of solar grass cutter.pdfDesign and analysis of solar grass cutter.pdf
Design and analysis of solar grass cutter.pdf
 
EduAI - E learning Platform integrated with AI
EduAI - E learning Platform integrated with AIEduAI - E learning Platform integrated with AI
EduAI - E learning Platform integrated with AI
 
Introduction-To-Agricultural-Surveillance-Rover.pptx
Introduction-To-Agricultural-Surveillance-Rover.pptxIntroduction-To-Agricultural-Surveillance-Rover.pptx
Introduction-To-Agricultural-Surveillance-Rover.pptx
 
Call Girls Delhi {Jodhpur} 9711199012 high profile service
Call Girls Delhi {Jodhpur} 9711199012 high profile serviceCall Girls Delhi {Jodhpur} 9711199012 high profile service
Call Girls Delhi {Jodhpur} 9711199012 high profile service
 
VICTOR MAESTRE RAMIREZ - Planetary Defender on NASA's Double Asteroid Redirec...
VICTOR MAESTRE RAMIREZ - Planetary Defender on NASA's Double Asteroid Redirec...VICTOR MAESTRE RAMIREZ - Planetary Defender on NASA's Double Asteroid Redirec...
VICTOR MAESTRE RAMIREZ - Planetary Defender on NASA's Double Asteroid Redirec...
 
Application of Residue Theorem to evaluate real integrations.pptx
Application of Residue Theorem to evaluate real integrations.pptxApplication of Residue Theorem to evaluate real integrations.pptx
Application of Residue Theorem to evaluate real integrations.pptx
 
CCS355 Neural Network & Deep Learning Unit II Notes with Question bank .pdf
CCS355 Neural Network & Deep Learning Unit II Notes with Question bank .pdfCCS355 Neural Network & Deep Learning Unit II Notes with Question bank .pdf
CCS355 Neural Network & Deep Learning Unit II Notes with Question bank .pdf
 
pipeline in computer architecture design
pipeline in computer architecture  designpipeline in computer architecture  design
pipeline in computer architecture design
 
Call Us -/9953056974- Call Girls In Vikaspuri-/- Delhi NCR
Call Us -/9953056974- Call Girls In Vikaspuri-/- Delhi NCRCall Us -/9953056974- Call Girls In Vikaspuri-/- Delhi NCR
Call Us -/9953056974- Call Girls In Vikaspuri-/- Delhi NCR
 
Concrete Mix Design - IS 10262-2019 - .pptx
Concrete Mix Design - IS 10262-2019 - .pptxConcrete Mix Design - IS 10262-2019 - .pptx
Concrete Mix Design - IS 10262-2019 - .pptx
 
Past, Present and Future of Generative AI
Past, Present and Future of Generative AIPast, Present and Future of Generative AI
Past, Present and Future of Generative AI
 
9953056974 Call Girls In South Ex, Escorts (Delhi) NCR.pdf
9953056974 Call Girls In South Ex, Escorts (Delhi) NCR.pdf9953056974 Call Girls In South Ex, Escorts (Delhi) NCR.pdf
9953056974 Call Girls In South Ex, Escorts (Delhi) NCR.pdf
 
Oxy acetylene welding presentation note.
Oxy acetylene welding presentation note.Oxy acetylene welding presentation note.
Oxy acetylene welding presentation note.
 
Heart Disease Prediction using machine learning.pptx
Heart Disease Prediction using machine learning.pptxHeart Disease Prediction using machine learning.pptx
Heart Disease Prediction using machine learning.pptx
 

C & ASM AN INTRODUCTION - ASM in C and Extended ASM

  • 1. 1 C & ASM AN INTRODUCTION Arun Umrao www.sites.google.com/view/arunumrao DRAFT COPY - GPL LICENSING
  • 2. 2 Contents 1 ASM in C 9 1.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 1.2 Extended ASM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 1.2.1 Volatile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 1.3 Operand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 1.4 Clobber List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 1.5 Constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 1.5.1 Common Constraints . . . . . . . . . . . . . . . . . . . . . . . . . . 15 1.5.2 Constraint Modifiers . . . . . . . . . . . . . . . . . . . . . . . . . . 18 1.6 Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 Addition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 Bitwise AND . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 Clear Carry Flag . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 Compare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 Copy Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 Decrements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 Increments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 Jump if Above . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 Jump to Address . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 Store Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 Negative of Number . . . . . . . . . . . . . . . . . . . . . . . . . . 25 Bitwise Not . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 Bitwise OR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 Rotate Bits Left Through Carry . . . . . . . . . . . . . . . . . . . 27 Rotate Bits Right Through Carry . . . . . . . . . . . . . . . . . . 27 Rotate to Left . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 Rotate to Right . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 Set Carry Flag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 Subtract . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 Bitwise Exclusive OR . . . . . . . . . . . . . . . . . . . . . . . . . 31 2 C in ASM 33 2.1 NASM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 2.1.1 Memory Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 2.1.2 Defining Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 2.1.3 Character Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 2.1.4 Local Label . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 2.1.5 Local Variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 2.1.6 Repeat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 2.1.7 Directives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 2.1.8 NASM File Layout . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 2.1.9 Calling External Functions . . . . . . . . . . . . . . . . . . . . . . 41 2.1.10 Uers’s Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 2.1.11 Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
  • 3. 3 2.1.12 Executing Command . . . . . . . . . . . . . . . . . . . . . . . . . . 50 2.2 Link ASM with C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
  • 5. 1.1. INTRODUCTION 5 1ASM in C In this chapter we shall discuss that how assembly codes can be executed within C codes. For this purpose, I use NetBean IDE with Cygwin compiler. Cygwin has default assembler as.exe. The representation of instructions and register symbols depend on the assembler type. For example, usage of mov instruction on a 32-bit architecture, GAS syntax is: ✞ 1 ;instruction source , destination movl $0x000F , %eax ; Store the value F into the ax register ✌ ✆ Some instructions, especially when built for Unix, Linux, etc., require the use of suffixes to specify the size of the data which will be the subject of the operation. For example, some possible suffixes are ‘b’ for byte (8 bits), ‘w’ for word (16 bits), ‘l’ for long (32 bits) and ‘q’ for quad (64 bits). For 64-bits assembly programming, ‘R’ is prefixed with each registers. ✞ movq $6 , %rax ; 64 bits code ✌ ✆ But on Intel Syntax we don’t have to use the suffix. Based on the register name and the used immediate value the compiler knows which data size to use. For example, ✞ 1 ;instruction destination , source MOV EAX , 0 x000F ✌ ✆ Therefore, while you are writing your assembly codes, please be careful about the as- sembler, OS and processor architecture type. Instruction OP codes, register name and hexadecimal data values are case insensitive, i.e. they can be written in upper case or in lower case or in mixed case to increase readability of the assembly codes. gcc has also capability to de-assemble the .c file into .asm file by using following command. ✞ gcc -S myc.c -o myc.asm ; Note for CAPITAL S ✌ ✆ gcc generates an equivalent assembly file. This assembly file can be compiled into exe- cutable with gcc by using following command. ✞ 1 gcc -o <outfile name > -m32 <asm file > ✌ ✆ Here, gcc calls the assembler (as) and the linker (ld) automatically to compile the assembly file. ‘-m32’ can be replaced with ‘-m64’ for 64-bits processors. 1.1 Introduction The format of basic inline assembly is very much straight forward. Its basic form is
  • 6. 6 ASM in C ✞ 1 asm(<assembly code >); ✌ ✆ We can write inline code in modified form if asm function is conflict with other same ‘c’ function . ✞ 1 __asm__(< assembly code >); ✌ ✆ 1.2 Extended ASM In basic inline assembly, there are only instructions. In extended assembly, we can also specify the operands. It allows us to specify the input registers, output registers and a list of clobbered registers. ✞ 1 __asm__ (assembler template : /* Optional output operands */ 3 : /* Optional input operands */ : /* Optional list of clobbered registers */ 5 : /* Jump to Goto Labels (optional ) */ ); ✌ ✆ The assembler template consists of assembly instructions. Each operand is described by an operand-constraint string followed by the C expression in parentheses. A colon (:) separates the assembler template from the first output operand and another separates the last output operand from the first input, if any. Commas separate the operands within each group. The total number of operands is limited to ten or to the maximum number of operands in any instruction pattern in the machine description, whichever is greater. ✞ #include <stdio.h> 2 int main () { 4 int in = 10, out; __asm__ ("movl %1, %% eax;" 6 "movl %%eax , %0;" : "=r" (out) /* Output */ 8 : "r" (in) /* Input */ : "%eax" /* Clobbered Register */ 10 ); printf("Output is %dn", out); 12 return 0; } ✌ ✆ ✞ Output is 10 ✌ ✆ Here it is made the value of C variable ‘out’ equal to that of C variable ‘in’ using assembly instructions. Here C variable ‘out’ is the output operand, referred to by %0 and C variable ‘in’ is the input operand, referred to by %1. r is a constraint on the operands. For the time being, r says to GCC to use any register for storing the operands. Output operand
  • 7. 1.2. EXTENDED ASM 7 constraint should have a constraint modifier “=”. And this modifier says that it is the output operand and is write-only. There are two %’s prefixed to the register name. This helps GCC to distinguish between the operands and registers. Operands have a single % as prefix. The clobbered register %eax after the third colon tells GCC that the value of %eax is to be modified inside asm, so GCC won’t use this register to store any other value. When the execution of asm is complete, ‘out’ will reflect the updated value, as it is specified as an output operand. In other words, the change made to C variable ‘out’ inside asm is supposed to be reflected outside the asm. Again, we can also get multiple outputs by accessing suitable registers as shown in the following example. ✞ 1 #include <stdio.h > 3 int main () { int out1 , out2 ; 5 __asm__ ("movl $8 , %% eax;" "movl $10 , %% ebx;" 7 : "=a" (out1 ), "=b" (out2 ) ); 9 printf("%d, %d", out1 , out2 ); return 0; 11 } ✌ ✆ ✞ 8, 10 ✌ ✆ The size of operand is crucial to determine the space required for execution of the op-code command. The size of memory operands is determined from the last character of the op- code name. For example, movl represents to the op-code mov which is being operated on the long data type. Similarly, other suffixes are ‘b’ for byte, ‘w’ for (16-bit) word, and ‘l’ for (32-bit) long. The symbol ‘$’ prefixed with a number tells to gcc that, the number value followed by it is immediately assigned to the register. Indexing or indirection is done by enclosing the index register or indirection memory cell address in parentheses. ✞ 1 movl 8(%% ebp), %% eax ✌ ✆ instruction tells that, the contents at offset 8 from the memory cell pointed to by ‘%ebp’ register is moved into into the register ‘%eax’. 1.2.1 Volatile The assembly codes in C are very susceptible to dangle beyond the scope of asm function. And it is a security reason to control their scope. Our assembly statement must execute where we put it, and they must not be moved out of a loop as an optimization. To do this, we put keyword “volatile” or “ volatile ” just after asm or “ asm ” and before the ()s. Its syntax is given below: ✞ 1 __asm__ __volatile__ ( "...; " "...; " : ... ); ✌ ✆ Example of use of volatile is given below:
  • 8. 8 ASM in C ✞ #include <stdio.h> 2 int main () { 4 int in = 10, out = 5; 6 __asm__ __volatile__ ( "addl %%ebx , %% eax" 8 /* Update var out by value of eax register */ : "=a" (out) 10 : "a" (in), "b" (out) ); 12 printf("in + out = %dn", out); return 0; 14 } ✌ ✆ ✞ in + out = 15 ✌ ✆ 1.3 Operand C Language Expressions (CLE) or C Language Variables (CLV) serve as operands for the assembly instructions inside asm. Each operand is a combination of constraints in double quote followed by C language variable or C language expression in parentheses. Prototype is ✞ 1 "constraint " (< CLV >) ✌ ✆ Constraints are primarily used to decide the addressing modes for operands. They are also used in specifying the registers to be used. If we use more than one operand, then they are separated by comma. In the assembler template, each operand is referenced by numbers from zero to n operands (including input and output both). First is output operand and it is numbered 0. Next are input operands which are counted from 1 to n−1. Output operand expressions must be left-values. The input operands are not restricted like this. Ordinary output operands must be write-only. Extended asm also supports input-output or read-write operands. Illustrated Example Assume that, we have to add 5 to the input value 10 and the answer should be retrieved through another variable. See the example below: ✞ 1 #include <stdio.h> 3 int main () { int in1 = 10, in2 = 5, out; 5 __asm__ ("movl %1, %% eax;" /* Operator , register , 2nd input*/ 7 "add %%eax , %2;" /* Output : "constraints " (<CLV >) */ 9 : "=r" (out) /* Two inputs : "constraints " (<CLV >) *
  • 9. 1.3. OPERAND 9 11 * Input count (%1) started right to left */ : "r" (in2), "r" (in1) 13 : "%eax" /* Clobbered register */ ); 15 printf("in1 + in2 is %d", out); return 0; 17 } ✌ ✆ ✞ in1 + in2 is 15 ✌ ✆ Here inputs are ‘in2’ and ‘in1’. Output is directly fetched from the register. Here, one point is to be noted that, register eax is prefixed with % symbol and also with %% symbol at different places. It is because the compiler copies the assembler instructions in a basic asm verbatim to the assembly language output file, without processing dialects or any of the ‘%’ operators that are available with extended asm. This results in minor differences between basic asm strings and extended asm templates. For example, to refer to registers you might use ‘%eax’ in basic asm and ‘%%eax’ in extended asm. Now if we want to specify the register then constraints representing to the register are used as shown in the following table. ✞ 1 #include <stdio.h> 3 int main () { int in1 = 10, in2 = 5, out; 5 __asm__ ("addl %%ebx , %% eax;"/* Add BX to AX register */ "movl %%eax , %% ecx;"/* Move value of AX to CX*/ 7 /* Output : "register constraints " (<CLV >) */ : "=c" (out) 9 /* Inputs : "register constraints " (<CLV >) */ : "a" (in2), "b" (in1) 11 ); printf("in1 + in2 is %d", out); 13 return 0; } ✌ ✆ ✞ in1 + in2 is 15 ✌ ✆ In above two examples, we didn’t put any register to the clobber list to let the free to GCC to decide it. As the constraints for input variable ‘in2’ is a, hence this input is directly stored in the register eax. Similarly, the constraints for input variable ‘in1’ is b, hence this input is directly stored in the register ebx. We move the result stored in eax to ecx register as constants of output variable ‘out’ is c, i.e. register ecx. We can assign a value directly to a register. To do so, movl command is used and value is preceded by ‘$’ sign as explained in the following example. ✞ 1 #include <stdio.h> 3 int main () { int out;
  • 10. 10 ASM in C 5 /* Add 10 and 20 and store * *result into register %eax*/ 7 __asm__ ("movl $10 , %% eax;" "movl $20 , %% ebx;" 9 "addl %%ebx , %% eax;" : "=a" (out) 11 ); printf("Sum is %d", out); 13 return 0; } ✌ ✆ ✞ Sum is 30 ✌ ✆ In case of you do not want to use any constraints, it is leaved blank after “:” symbol as shown in the following example. ✞ 1 #include <stdio.h> 3 int main () { int out; 5 /* Add 10 and 20 and store * *result into register %eax*/ 7 __asm__ ("movl $10 , %% eax;" "movl $20 , %% ebx;" 9 "addl %%ebx , %% eax;" : "=r" (out) 11 : /* Order should be maintained */ : "%ebx" 13 ); printf("Sum is %d", out); 15 return 0; } ✌ ✆ ✞ Sum is 30 ✌ ✆ 1.4 Clobber List Registers are used to store inputs and outputs by the GCC. If we use the r constraint type then GCC itself selects the registers in which inputs and outputs are to be stored. This is why, the output register is remains unknown to the user. This is why, we inform GCC that we will use and modify the specific register. Clobber list is the register name placed after third “:” operator as shown below: ✞ 1 #include <stdio.h> 3 int main () { int in1 = 10, in2 = 5, out; 5 __asm__ ("movl %1, %% eax;"
  • 11. 1.5. CONSTRAINTS 11 "add %%eax , %2;" 7 : "=r" (out) /* Output */ : "r" (in2), "r" (in1) /* Inputs */ 9 : "%eax" /* Clobbered Register */ ); 11 printf("in1 + in2 is %d", out); return 0; 13 } ✌ ✆ ✞ in1 + in2 = 15 ✌ ✆ In Clobber list, those registers are defined which are not present either in input or in the output constraint list. 1.5 Constraints Constraints tells whether an operand is a register and which kind of it is. Similarly, it tells whether operand is a memory reference and which kinds of memory address is¿ It also tells that whether the operand is an immediate constant and what value it stored. 1.5.1 Common Constraints There are a number of constraints of which only a few are used frequently. We’ll have a look at those constraints. Register Operand Constraint(r) When operands are specified using this constraint, they get stored in General Purpose Registers(GPR). Take the following example: ✞ 1 __asm__ ( "movl %%eax , %0n" 3 :"=r" (<my C variable >) ); ✌ ✆ Here the variable ‘my C variable’ is kept in a register, the value in register eax is copied onto that register, and the value of ‘my C variable’ is updated into the memory from this register. When the r constraint is specified, GCC may keep the variable in any of the available GPRs. To specify the register, you must directly specify the register names by using specific register constraints. They are:
  • 12. 12 ASM in C Constraints Register (s) a %eax, %ax, %al b %ebx, %bx, %bl c %ecx, %cx, %cl d %edx, %dx, %dl S %esi, %si D %edi, %di Memory Operand Constraint(m) When the operands are in the memory, any operations performed on them will occur directly in the memory location, as opposed to register constraints, which first store the value in a register to be modified and then write it back to the memory location. But register constraints are usually used only when they are absolutely necessary for an instruction or they significantly speed up the process. Memory constraints can be used most efficiently in cases where a C variable needs to be updated inside asm and you really don’t want to use a register to hold its value. For example, the value of ‘idtr’ is stored in the memory location: ✞ __asm__ ( 2 "sidt %0n" : 4 :"m" (<memory location >) ); ✌ ✆ Matching(Digit) Constraints In some cases, a single variable may serve as both the input and the output operand. Such cases may be specified in asm by using matching constraints. ✞ 1 __asm__ ( "incl %0" 3 :"=a" (<C Language Variable >) :"0" (<C Language Variable >) 5 ); ✌ ✆ We saw similar examples in operands subsection also. In this example for matching constraints, the register %eax is used as both the input and the output variable. var input is read to %eax and updated %eax is stored in var again after increment. “0” here specifies the same constraint as the 0th output variable. That is, it specifies that the output instance of var should be stored in %eax only. This constraint can be used: New Case In cases where input is read from a variable or the variable is modified and modification is written back to the same variable. New Case In cases where separate instances of input and output operands are not necessary.
  • 13. 1.5. CONSTRAINTS 13 The most important effect of using matching restraints is that they lead to the efficient use of available registers. r Explanation “m” A memory operand is allowed, with any kind of ad- dress that the machine supports in general “o” A memory operand is allowed, but only if the address is offset table, i.e. adding a small offset to the address gives a valid address “V” A memory operand that is not offset table. In other words, anything that would fit the ‘m’ constraint but not the ‘o’constraint “i” An immediate integer operand (one with constant value) is allowed. This includes symbolic constants whose values will be known only at assembly time “n” An immediate integer operand with a known nu- meric value is allowed. Many systems cannot sup- port assembly-time constants for operands less than a word wide. Constraints for these operands should use ‘n’ rather than ‘i’ “g” Any register, memory or immediate integer operand is allowed, except for registers that are not general registers See the example given below: ✞ 1 #include <stdio.h> 3 int main () { int in1 = 10, in2 = 5; 5 __asm__ __volatile__ ("lock ;n" 7 "addl %1, %0; n" : "=m" (in1) 9 : "ir" (in2), "m" (in1) ); 11 printf("in1 + in2 = %dn", in2); return 0; 13 } ✌ ✆ ✞ in1 + in2 = 15 ✌ ✆ This is an atomic addition. We can remove the instruction ‘lock’ to remove the atomicity. In the output field, =m says that ‘b’ is an output and it is in memory. Similarly, ir says
  • 14. 14 ASM in C that, ‘a’ is an integer and should reside in some register. No registers are in the clobber list. Following constraints are x86 specific. Constraints Explanation Constraints Register Operand Constraint “q” Registers a, b, c or d “I” Constant in range 0 to 31 (for 32-bit shifts) “J” Constant in range 0 to 63 (for 64-bit shifts) “K” 0xff “L” 0xffff “M” 0, 1, 2, or 3 (shifts for lea instruction) “N” Constant in range 0 to 255 (for out instruction) “f” Floating point register “t” First (top of stack) floating point register “u” Second floating point register “A” Specifies the ‘a’ or ‘d’ registers. This is primarily use- ful for 64-bit integer values intended to be returned with the ‘d’ register holding the most significant bits and the ‘a’ register holding the least significant bits 1.5.2 Constraint Modifiers While using constraints, for more precise control over the effects of constraints, GCC provides us with constraint modifiers. Mostly used constraint modifiers are Constraints Explanation “=” Means that this operand is write-only for this in- struction; the previous value is discarded and re- placed by output data “&” Means that this operand is an early clobber operand, which is modified before the instruction is finished using the input operands. Therefore, this operand may not lie in a register that is used as an input operand or as part of any memory address. An input operand can be tied to an early clobber operand if its only use as an input occurs before the early result is written
  • 15. 1.6. INSTRUCTIONS 15 1.6 Instructions In this section important operators are explained by giving suitable examples. The similar operators can be used similarly. in GCC, asm instruction set direction is from left to right, i.e. for example, add instruction has syntax like ✞ 1 add <source register >, <destination register >; ✌ ✆ Each instruction is terminated by “;” symbol. If constraint type is r then, GCC automat- ically select the register for input and output. If constraint type is not r then instruction sets are executed according to the above syntax. Addition add instruction adds the contents of two source and destination operands and stores the sum in destination register. See the example below: ✞ 1 #include <stdio.h> 3 int main () { int in = 10, out; 5 __asm__ ("movl %1, %% eax;" "addl %%eax , %1;"/* Operator , register , input*/ 7 : "=r" (out) /* Output , auto constraint */ : "r" (in) /* One input , auto constraint */ 9 : "%eax" /* Clobbered register */ ); 11 printf("out is %d", out); return 0; 13 } ✌ ✆ ✞ out is 20 ✌ ✆ Here, constraint type is r, hence the data is stored in any register and it is decided by GCC and register is selected by Clobbered Register list. This is why, in above example, sum of register eax and input is stored in eax register. We can supply the input value directly rather than through usual inputs. Here decimal 52 is supplied to AX register directly. ✞ 1 #include <stdio.h> 3 int main () { int in = 10, out; 5 __asm__ ("movl $52 , %% eax;" "addl %%eax , %1;"/* Operator , register , input */ 7 : "=r" (out) /* Output , auto constraint */ : "r" (in) /* One input , auto constraint */ 9 : "%eax" /* Clobbered register */ ); 11 printf("out is %d", out);
  • 16. 16 ASM in C return 0; 13 } ✌ ✆ ✞ out is 62 ✌ ✆ Another example of summation. ✞ 1 #include <stdio.h> 3 int main () { int in1 = 10, in2 = 17, out; 5 __asm__ ("movl $52 , %% eax;" "addl %%eax , %2;" 7 /* Output , auto constraint */ : "=r" (out) 9 /* Two inputs , auto constraint */ : "r" (in2), "r" (in1) 11 : "%eax" /* Clobbered register */ ); 13 printf("out is %d", out); return 0; 15 } ✌ ✆ ✞ out is 69 ✌ ✆ Bitwise AND AND is short name of Bitwise AND. The output is 1 if both operand bits are 1 and otherwise their AND is 0. ✞ 1 0010 0101 : X=37 0101 0010 : Y=82 3 ---------------- AND 0000 0000 : 0 ✌ ✆ See the example below: ✞ #include <stdio.h> 2 int main () { 4 int out; __asm__ ("movl $37 , %% eax;" 6 "movl $82 , %% ebx;" "and %%eax , %% ebx;" 8 : "=b" (out) ); 10 printf("AND of 37 and 82 is %d", out); return 0; 12 } ✌ ✆
  • 17. 1.6. INSTRUCTIONS 17 ✞ AND of 37 and 82 is 0 ✌ ✆ The ANDed result of two operands is stored in second register, i.e. in ebx register. Clear Carry Flag clc instruction clears the previously set carry flag. To see its working, two consecutive examples are given. In the following example, carry flag is set to high. Thus a jump is take place to ‘HERE’ offset. This skips the increment of eax register. So the final output is −10. ✞ 1 #include <stdio.h> 3 int main () { int out; 5 __asm__ ("movl $10 , %% eax;" "stc;" /* Set carry flag .*/ 7 "jc HERE ;" /* Jump to HERE .*/ "inc %% eax;" /* Skipped.*/ 9 "HERE : ;" "neg %% eax;" /* Executed */ 11 : "=a" (out) ); 13 printf("Negative of 10 is %d", out); return 0; 15 } ✌ ✆ ✞ Negative of 10 is -10 ✌ ✆ In the above example, clc instruction is placed just below to stc instruction. It skips the jump on carry and inc instruction is executed. Now the final value is −11. ✞ 1 #include <stdio.h> 3 int main () { int out; 5 __asm__ ("movl $10 , %% eax;" "stc;" /* Set carry flag .*/ 7 "clc;" /* Clear carry flag .*/ "jc HERE ;" /* No jump to HERE */ 9 "inc %% eax;" /* Executed */ "HERE : ;" 11 "neg %% eax;" /* Executed */ : "=a" (out) 13 ); printf("Negative of 10 is %d", out); 15 return 0; } ✌ ✆
  • 18. 18 ASM in C ✞ Negative of 10 is -11 ✌ ✆ Compare cmp compares the source operand from the destination operand. It updates the flags as the sub instruction. It does not alter the source and destination operands. Flags are sets according to: if first operand is equal to second operand (ZF = 1 and CF = 0), first operand is less than the second operand (ZF = 1 and CF = 1) or first operand is greater than the second operand (ZF = 0 and CF = 0). According to this result, jump function is executed. ✞ 1 #include <stdio.h> 3 int main () { int out; 5 __asm__ ("movl $1 , %% eax;" /*AX = 1 */ "movl $10 , %% ebx;" /*BX = 10*/ 7 "movl $15 , %% ecx;" /*CX = 15*/ "A : ;" /* Loop offset*/ 9 "inc %% eax;" /*AX = AX + 1*/ "addl %%ebx , %% ecx;"/*CX = CX + BX*/ 11 "cmp %%eax , %% ebx;" /*ZF = CF = 0, if AX > BX*/ "ja A;" /* Jump to Offset */ 13 : "=c" (out) ); 15 printf("Output is %d", out); return 0; 17 } ✌ ✆ ✞ Output is 105 ✌ ✆ Copy Data mov instruction with proper suffix (i.e. ‘b’ for 8 bits byte data, ‘w’ for 16 bits word data, ‘l’ for 32 bits long data and ‘q’ for 64 bits quad data) to copy data into registers. See the example below: ✞ 1 #include <stdio.h> 3 int main () { char *in1="This is my string"; 5 char *out; __asm__ ("movl %1, %% eax;" 7 /* Output , auto constraint */ : "=r" (out) 9 /* Two inputs , auto constraint */ : "r" (in1)
  • 19. 1.6. INSTRUCTIONS 19 11 : "%eax" /* Clobbered register */ ); 13 printf("out is ’%s’", out); return 0; 15 } ✌ ✆ ✞ out is ’This is my string ’ ✌ ✆ mov instruction accepts two arguments, first is source and second is destination in GAS assembler. Decrements dec subtracts one from the operand, it does not affect CF. If value of operand is decimal 52 then it shall made this value to 52 − 1 = 51. ✞ 1 #include <stdio.h> 3 int main () { int out; 5 __asm__ ("movl $52 , %% eax;" "dec %% eax;" 7 : "=a" (out) ); 9 printf("out is %d", out); return 0; 11 } ✌ ✆ ✞ out is 51 ✌ ✆ Increments It increments the value of operands by one. If value of operand is decimal 52 then it shall made this value to 52 + 1 = 53. ✞ 1 #include <stdio.h> 3 int main () { int out; 5 __asm__ ("movl $52 , %% eax;" "inc %% eax;" 7 : "=a" (out) ); 9 printf("out is %d", out); return 0; 11 } ✌ ✆ ✞ out is 53 ✌ ✆
  • 20. 20 ASM in C Jump if Above ja is acronym of ‘Jump if Above’. Each jump condition is preceded by a cmp function. First cmp compare the two operands and returns the status, i.e. first operand is equal to second operand (ZF = 1 and CF = 0), first operand is less than the second operand (ZF = 1 and CF = 1) or first operand is greater than the second operand (ZF = 0 and CF = 0). According to this result, jump function is executed. ✞ 1 #include <stdio.h> 3 int main () { int out; 5 __asm__ ("movl $1 , %% eax;" /*AX = 1 */ "movl $10 , %% ebx;" /*BX = 10*/ 7 "movl $15 , %% ecx;" /*CX = 15*/ "A : ;" /* Loop offset*/ 9 "inc %% eax;" /*AX = AX + 1*/ "addl %%ebx , %% ecx;"/*CX = CX + BX*/ 11 "cmp %%eax , %% ebx;" /*ZF = CF = 0, if AX > BX*/ "ja A;" /* Jump to Offset */ 13 : "=c" (out) ); 15 printf("Output is %d", out); return 0; 17 } ✌ ✆ ✞ Output is 105 ✌ ✆ Jump to Address jmp unconditionally transfers control to the target location. The destination address can be specified directly within the instruction or indirectly through a register or memory, the acceptable size of this address depends on whether the jump is near or far (it can be specified by preceding the operand with near or far operator) and whether the instruction is 16-bit or 32-bit. ✞ 1 #include <stdio.h> 3 int main () { int outa , outb , outc ; 5 __asm__ ("movl $1 , %% eax;" /*AX = 1 */ "movl $10 , %% ebx;" /*BX = 10*/ 7 "movl $15 , %% ecx;" /*CX = 15*/ "jmp HERE ;" /* Jump to Offset HERE */ 9 "inc %% eax;" /*AX = AX + 1*/ "addl %%ebx , %% ecx;"/*CX = CX + BX*/ 11 "cmp %%eax , %% ebx;" /*ZF = CF = 0, if AX > BX*/ "HERE : ;" /* Location offset*/ 13 : "=a" (outa ), "=b" (outb ), "=c" (outc ) );
  • 21. 1.6. INSTRUCTIONS 21 15 printf("AX , BX and CX are %d, %d and %d", outa , outb , outc ); return 0; 17 } ✌ ✆ ✞ AX , BX and CX are 1, 10 and 15 ✌ ✆ As there is jump, hence inc, addl and cmp instructions are not executed and the initial values of registers are obtained. Store Data movb instruction is used to store a byte in a register and movl instruction is used to store a long data value into a register. movb is always followed by one byte long register represented like ‘%al’ or ‘%ah’. movw is used to store 16 bits long data in 16 bits register, like ‘%ax’ register. Note that ‘%ax’ is two byte long data whose lower 8 bits are represented by ‘%al’ register and upper 8 bits are represented by ‘%ah’ register. movl is used to store extra long data, i.e. 32 bits long data. This instruction is followed by 32 bits register represented like ‘%eax’, ‘%ebx’ etc. ✞ 1 #include <stdio.h> 3 int main () { int in = 10, out; 5 /* Operator input , destination */ __asm__ ("movl %1, %% eax;" 7 : "=r" (out)/* output */ : "r" (in) /* input */ 9 : "%eax" /* clobbered register */ ); 11 printf("out is %d", out); return 0; 13 } ✌ ✆ ✞ out is 10 ✌ ✆ Negative of Number It converts a number into negative number. If operand value is 10 then this instruction makes the number −10. ✞ 1 #include <stdio.h> 3 int main () { int out; 5 __asm__ ("movl $10 , %% eax;" "neg %% eax;" 7 : "=a" (out) );
  • 22. 22 ASM in C 9 printf("Negative of 10 is %d", out); return 0; 11 } ✌ ✆ ✞ Negative of 10 is -10 ✌ ✆ Bitwise Not not is short name of Bitwise NOT. It inverts the bits of a binary number. ✞ 1 0010 0101 : X=37 ---------------- OR 3 1101 1010 : 218 ✌ ✆ NOT of a number, n, is computed either by inverting the binary bits or by using (−(n+1)) rule. See the example given below: ✞ 1 #include <stdio.h> 3 int main () { int out; 5 __asm__ ("movl $37 , %% eax;" "not %% eax;" 7 : "=a" (out) ); 9 printf("NOT of 37 is %d", out); return 0; 11 } ✌ ✆ ✞ NOT of 37 is -38 ✌ ✆ Bitwise OR OR is short name of Bitwise OR. The output is 1 if either of the two operands or both operands are 1 and 0 otherwise. ✞ 1 0010 0101 : X=37 0101 0010 : Y=82 3 ---------------- OR 0111 0111 : 119 ✌ ✆ See the example given below: ✞ #include <stdio.h> 2 int main () { 4 int out; __asm__ ("movl $37 , %% eax;"
  • 23. 1.6. INSTRUCTIONS 23 6 "movl $82 , %% ebx;" "or %%eax , %% ebx;" 8 : "=b" (out) ); 10 printf("OR of 37 and 82 is %d", out); return 0; 12 } ✌ ✆ ✞ OR of 37 and 82 is 119 ✌ ✆ The ORed result of two operands is stored in second register, i.e. in ebx register. Rotate Bits Left Through Carry rcl is short name of ‘Rotate Bits Left Through Carry’. It rotate the byte, word or double word destination operand left by the number of bits specified in the second operand. rcl additionally puts in CF each high order bit that exits from the left side of the operand before it returns to the operand as the low order bit on the next rotation cycle. ✞ 1 #include <stdio.h> 3 int main () { int out; 5 __asm__ ("movl $10 , %% eax;" "rcl %% eax;" 7 : "=a" (out) ); 9 printf("RCL of 10 is %d", out); return 0; 11 } ✌ ✆ ✞ RCL of 10 is 20 ✌ ✆ Rotate Bits Right Through Carry rcl is short name of ‘Rotate Bits Right Through Carry’. It rotate the byte, word or double word destination operand right by the number of bits specified in the second operand. For each rotation, rcr additionally puts in CF each low order bit that exits from the right side of the operand before it returns to the operand as the high order bit on the next rotation cycle. ✞ 1 #include <stdio.h> 3 int main () { int out; 5 __asm__ ("movl $10 , %% eax;" "rcr %% eax;" 7 : "=a" (out)
  • 24. 24 ASM in C ); 9 printf("RCR of 10 is %d", out); return 0; 11 } ✌ ✆ ✞ RCR of 10 is 5 ✌ ✆ Rotate to Left rol rotate the byte, word or double word destination operand left by the number of bits specified in the second operand. For each rotation specified, the high order bit that exits from the left of the operand returns at the right to become the new low order bit. ✞ 1 org 100h ; 254 -> 1111 1110 3 mov ax , 254 ; Initial value of AX ; ROL 254 by 1 bit left -> 1111 1101 5 ; It is equal to decimal 252 or FC hex rol ax , 1 ; Binary left shift by one bit 7 ret ✌ ✆ Above assembly language is translated into C program as given below: ✞ 1 #include <stdio.h> 3 int main () { int out; 5 __asm__ ( "movl $254 , %% ebx;" 7 "rol %% ebx;" : "=b" (out) 9 ); printf("ROL of 254 is %d", (out & 256) ); 11 return 0; } ✌ ✆ ✞ ROL of 254 is 252 ✌ ✆ Another example similar to above program is given below: ✞ 1 #include <stdio.h> 3 int main () { int out; 5 __asm__ ( "movl $254 , %% ebx;" 7 "rol %% ebx;" "rol %% ebx;" 9 : "=b" (out)
  • 25. 1.6. INSTRUCTIONS 25 ); 11 printf("Twice ROL of 254 is %d", (out & 256) ); return 0; 13 } ✌ ✆ ✞ Twice ROL of 254 is 248 ✌ ✆ Rotate to Right rorrotate the byte, word or double word destination operand right by the number of bits specified in the second operand. For each rotation specified, the low order bit that exits from the right of the operand returns at the left to become the new high order bit. ✞ 1 org 100h ; 254 -> 1111 1110 3 mov ax , 254 ; Initial value of AX ; ROR 254 by 1 bit right -> 0111 1111 5 ; It is equal to decimal 127 or 7F hex ror ax , 1 ; Binary left shift by one bit 7 ret ✌ ✆ ✞ 1 #include <stdio.h> 3 int main () { int out; 5 __asm__ ( "movl $254 , %% ebx;" 7 "ror %% ebx;" : "=b" (out) 9 ); printf("ROR of 254 is %d", out); 11 return 0; } ✌ ✆ ✞ ROR of 254 is 127 ✌ ✆ Set Carry Flag It sets carry flat to high. In the following example, carry flag is set to high. Thus a jump is take place to ‘HERE’ offset. This skips the increment of eax register. So the final output is −10. ✞ 1 #include <stdio.h> 3 int main () { int out; 5 __asm__ ("movl $10 , %% eax;"
  • 26. 26 ASM in C "stc;" /* Set carry flag .*/ 7 "jc HERE ;" /* Jump to HERE .*/ "inc %% eax;" /* Skipped.*/ 9 "HERE : ;" "neg %% eax;" /* Executed */ 11 : "=a" (out) ); 13 printf("Negative of 10 is %d", out); return 0; 15 } ✌ ✆ ✞ Negative of 10 is -10 ✌ ✆ In the above example, clc instruction is placed just below to stc instruction. It skips the jump on carry and inc instruction is executed. Now the final value is −11. ✞ 1 #include <stdio.h> 3 int main () { int out; 5 __asm__ ("movl $10 , %% eax;" "stc;" /* Set carry flag .*/ 7 "clc;" /* Clear carry flag .*/ "jc HERE ;" /* No jump to HERE */ 9 "inc %% eax;" /* Executed */ "HERE : ;" 11 "neg %% eax;" /* Executed */ : "=a" (out) 13 ); printf("Negative of 10 is %d", out); 15 return 0; } ✌ ✆ ✞ Negative of 10 is -11 ✌ ✆ Subtract sub instruction subtracts the contents of two operands and stores the sum in first operands, i.e. register. See the example below: ✞ 1 #include <stdio.h> 3 int main () { int in1 = 10, in2 = 15, out; 5 __asm__ ("movl %1, %% eax;" "sub %%eax , %2;" /* Operator , register , input*/ 7 : "=r" (out) /* Output */ : "r" (in2), "r" (in1) /* Two input */ 9 : "%eax" /* Clobbered register */
  • 27. 1.6. INSTRUCTIONS 27 ); 11 printf("out is %d", out); return 0; 13 } ✌ ✆ ✞ out is -5 ✌ ✆ Bitwise Exclusive OR XOR is short name of Bitwise Exclusive OR. The output is 1 if either of the two operands are 1 and is 0 if both operands are 1 or 0. ✞ 1 0010 0101 : X=37 0101 0010 : Y=82 3 ---------------- XOR 0111 0111 : 119 ✌ ✆ See the example given below: ✞ #include <stdio.h> 2 int main () { 4 int out; __asm__ ("movl $37 , %% eax;" 6 "movl $82 , %% ebx;" "xor %%eax , %% ebx;" 8 : "=b" (out) ); 10 printf("XOR of 37 and 82 is %d", out); return 0; 12 } ✌ ✆ ✞ XOR of 37 and 82 is 119 ✌ ✆
  • 28. 28 C in ASM
  • 29. 2.1. NASM 29 2C in ASM C and Assembly Languages can be used together to provide extra flexibility in programs specially in embedded systems. Here, libraries are created in one language and they are assessed from other languages. For correct linking, object files are created from .asm or from .c program codes and then they are called from other programs by linking them externally. Here, NASM assembler in linux OS is used to write libraries in assembly language. Note that, NASM uses different code structures and symbols in different OS. This is why, first we look into basic of NASM. 2.1 NASM The simplest and minimal command required to compile an assembly file into executable file is given below: ✞ 1 nasm -f <format > <input file > -o <output file > ✌ ✆ NASM is case sensitive compiler, for example, ‘HERE’, ‘Here’ and ‘here’ are three different labels for NASM. NASM uses following flags during the execution of nasm. -o This flag is used to force NASM to produce output file whose name is supplied just after this flag. If this flag is not used, then default file name is accepted automatically by nasm. -f This flag is used to force the NASM to compile assembly file into format file. If this flag is not provided, NASM selects file format automatically, i.e. binary file format. The accepted formats are elf, bin. Other accepted file format shall be listed by using -hf flag. -i This flag is used to make a directory searchable to include file at the path followed by this flag. The path name should be windows or Linux compatible. -l This flag is used to generate a source-listing file. -M This flag generates makefile dependencies. Flag -MG can be used to generate makefile dependencies on stdout. This differs from the -M option in that if a non-existing file is encountered, it is assumed to be a generated file and is added to the dependency list without a prefix. Note that, in Windows OS, an assembly file is complied as ✞ 1 nasm -fwin32 <file.asm > gcc <file.obj > ✌ ✆ while in Linux OS, it is compiled as ✞ nasm -felf <file.asm > 2 gcc <file.o > ✌ ✆
  • 30. 30 C in ASM One more thing, in Windows OS and with NASM, a function is always prefixed with a underscore, while in Linux OS, leading underscores from function name should be removed. 2.1.1 Memory Reference NASM was designed with simplicity of syntax in mind. One of the design goals of NASM is that it should be possible, as far as is practical. NASM have a much simpler syntax for memory references. The rule is simply that any access to the contents of a memory location requires square brackets around the address, and any access to the address of a variable doesnt. So an instruction of the form ✞ mov ax ,foo ✌ ✆ always refer to a compiletime constant, whether its an EQU or the address of a variable. To access the contents of the variable ‘foo’, you must code ✞ 1 mov ax ,[ foo] ✌ ✆ NASM does not support the hybrid syntaxes like ✞ 1 mov ax ,foo[bx] ✌ ✆ The correct syntax for the above is ✞ 1 mov ax ,[ foo+bx] ✌ ✆ 2.1.2 Defining Constants EQU defines a symbol to a given constant value. The action of EQU is to define the given label name to the value of its (only) operand. This definition is absolute, and cannot change later. See the example, ✞ 1 myMsg db ’hello , world’ myMsgLen equ $ m y M s g ✌ ✆ defines ‘myMsgLen’ to be the constant 12. ‘myMsgLen’ may not then be redefined later. The value of ‘myMsgLen’ is evaluated once, using the value of ‘$’ at the point of definition, rather than being evaluated wherever it is referenced and using the value of ‘$’ at the point of reference. 2.1.3 Character Strings A character string consists of up to eight characters enclosed in either single quotes (‘...’), double quotes (“...”) or backquotes (‘...‘). Strings enclosed in backquotes support Cstyle escapes for special characters, like single quote (), " double quote (”) etc. Unicode characters specified with u or U are converted to UTF8.
  • 31. 2.1. NASM 31 2.1.4 Local Label NASM gives special treatment to symbols beginning with a period, i.e. (.). A label beginning with a single period (.) is treated as a local label, which means that it is associated with the previous nonlocal label suffixed with colon (:) or not. So, for example: ✞ label1: ; some code 2 .loop ; some more code 4 jne .loop ret 6 label2: ; some code .loop 8 ; some more code jne .loop 10 ret ✌ ✆ In the above code fragment, each JNE instruction jumps to the line immediately before it, because the two definitions of .loop are kept separate by virtue of each being associated with the previous nonlocal label. If there is need to jump specific local label then it should be write as to, you could write ✞ label1: ; a n o n l o c a l label 2 .loop ; some more code 4 jne .loop ret 6 label2: ; another n o n l o c a l label .loop 8 ; some more code jne .loop 10 jmp label1.loop ret ✌ ✆ NASM has the capacity to define other special symbols beginning with a double period, i.e. (..). for example, ..start is used to specify the entry point in the obj output format. So just keep in mind that symbols beginning with a double period (..) are special. ✞ 1 label: ; a n o n l o c a l label ..@loop 3 ; some more code jmp ..@loop 5 ret ✌ ✆ 2.1.5 Local Variable When we enter into a into a function or subroutine, compiler pushes the address of the function/subroutine and its all arguments (in case of C program) into the stack pointer where control is to be returned (by using ret instruction) after successful execution of function/subroutine. After entering into a function, if function has local variables (if
  • 32. 32 C in ASM any), then there is need for reserve space for these local variables. We have to make space for local variables by decrementing the stack pointer using sub instruction. Consider a C function ✞ 1 int myExp(int i, int j) { int a, b, c; // Three local variables 3 b = 7; /* Local variable required * *to store value for b */ 5 return i * b + j; } ✌ ✆ The stock pointer of the function shall be looked like esp esp-4 esp-8 rAddr of myExp Addr of i Addr of j High to Low Here, ‘rAddr’ is abbreviation of ‘return address’. As the function has three local variables ‘a’, ‘b’ and ‘c’ and their address are need to store in stock pointer so that we can track and retrieve values of these local variables. For this we can either use to sub keyword to make space for these three local variables. See the assembly translated to above C function is given below: ✞ myExp: 2 sub esp , 12 ; makes room for 3 ints mov dword [esp+4], 7 ; b = 7 4 mov eax , [esp +16] ; i imul eax , [esp +4] ; i * b 6 add eax , [esp +20] ; i * b + j ret ✌ ✆ The stock pointer of the function shall be looked like esp esp-4 esp-8 esp-12 esp-16 esp-20 Addr of a Addr of b Addr of c rAddr of myExp Addr of i Addr of j High to Low
  • 33. 2.1. NASM 33 But sometimes it is a possible to track the offsets of your parameters and local vari- ables because the stack pointer keeps changing. Mostly within the nested functions or subroutines. For example ✞ 1 int myExp(int i, int j) { int a, b, c; // Three local variables 3 myFunc(i, a, b, c, j); 5 } ✌ ✆ Here, ‘myExp’ function pushes the addresses for itself and variables ‘i’ and ‘j’ into the stack pointer. Now stack pointer is pushes lower to store values for three local variables ‘a’, ‘b’ and ‘c’ by using sub instruction. When subroutine for ‘myFunc’ is translated, again address of ‘myFunc’ and five variables are pushed (by using push instruction) into the stack pointer. Now the final stack pointer structure is looked like esp esp-4 esp-8 esp-12 esp-16 esp-20 esp-24 esp-28 esp-32 esp-36 esp-40 esp-44 Addr of a Addr of b Addr of c rAddr of myExp Addr of i Addr of j rAddr of myFunc Addr of i Addr of a Addr of b Addr of c Addr of j High to Low Memory Here, values of all variables are pushed at different memory address in duplicate. Due to this, many functions use the ‘EBP’ register to index the “stack frame” of local variables and parameters, like this: ✞ push ebp ; Must save old ebp 2 mov ebp , esp ; point ebp to this frame sub esp , <n> ; make spaces for n local variables 4 <your codes here > mov esp , ebp ; clean up locals 6 pop ebp ; restore old ebp ret ✌ ✆ As long as we never change ‘EBP’ in the function, all local variables and parameters will always be at the same offset from ‘EBP’. The stack frame for this example is looked like
  • 34. 34 C in ASM ebp+12 ebp+8 ebp+4 ebp ebp-4 ebp-8 ebp-12 Addr of a Addr of b Addr of c Addr of old EBP rAddr of myFunc Addr of i Addr of j High to Low Memory To be familiar with stack/base pointer, see the following C examples and the stack pointers for C functions as given below: ✞ 1 #include <stdio.h> int ArrSum(unsigned len , int arr []); 3 int main (void ){ int nums [4], sum , n=4; 5 sum = ArrSum(n, nums ); return 0; 7 } ✌ ✆ The stock/base pointer of the function ‘myArrSum’ shall be looked like ebp ebp-4 ebp-8 ebp-12 Addr of old EBP rAddr of ArrSum Addr of n Addr of nums esp esp-4 esp-8 rAddr of ArrSum Addr of n Addr of nums High to Low When a program is called from commandline, then its stack/base pointer is looked like as given below: ✞ 1 #include <stdio.h> int main (int argc , char ** argv ){ 3 } --> ./ myProg "a" 45 ✌ ✆ The stock/base pointer of the function ‘myArrSum’ shall be looked like ebp ebp-4 ebp-8 ebp-12 Addr of old EBP rAddr of myProg Addr of argc Addr of argv esp esp-4 esp-8 rAddr of myProg Addr of argc Addr of argv High to Low
  • 35. 2.1. NASM 35 2.1.6 Repeat The TIMES prefix causes the instruction to be assembled multiple times. The argument to TIMES is not just a numeric constant, but a numeric expression, so you can do things like ✞ buff : db ’hello , world’ 2 times 64 $ +buff db ’ ’ ✌ ✆ which will store exactly enough spaces to make the total length of buffer up to 64. The operand to TIMES is a critical expression and it can’t be applied to macros. Its reason is that TIMES is processed after the macro phase, which allows the argument to TIMES to contain expressions. 2.1.7 Directives Extern extern is similar to the C keyword extern that is used to declare a symbol which in some other modules and needed by the current module. The extern directive may takes one or more arguments separated with comma. ✞ extern printf 2 extern printf , scanf ✌ ✆ If a variable is declared both global and extern, or as extern then it will be treated as global. If a variable is declared both as common and extern, it will be treated as common. Global global keyword is used to declare program location from where the program begins to execute. ✞ global main 2 main : <codes > ✌ ✆ Global like extern allows object formats to define private extensions by means of a colon. The elf object format lets specify whether global data items are functions or data. Global takes only one argument at a time. Common It defines common data area. It is used to declare common variables. A common variable is much like a global variable declared in the uninitialized data section. The difference is that if more than one module defines the same common variable, then at link time those variables will be merged, and references to common variable in all modules will point at the same piece of memory. Static It refers to the references for local symbols within the modules. This key- word/directive marks a variable as local symbol. Unlike global, static does not allow object formats to accept private extensions. Org org directive is to specify the origin address which NASM will assume the program begins at when it is loaded into memory.
  • 36. 36 C in ASM ✞ 1 org 0x100 dd label 3 label: <codes > ✌ ✆ org 0x100 NASM’s org directive says origin. Its sole function is to specify one offset which is added to all internal address references within the section. 2.1.8 NASM File Layout The simplest structure of NASM file layout is appeared as ✞ <label >: <instruction operands > ; <comment > ✌ ✆ These fields are optional. They may be present or not in a NASM assembly file. NASM uses backslash () as the line continuation character. It does not place restrictions on white space within a line. A label may have white space before them, or instructions may have no space before them, or anything. The colon after a label is also optional. Valid characters in labels are letters, numbers, ‘ ’, ‘$’, ‘#’, ‘@’, ‘˜ ’, ‘.’, and ‘?’. Labels must be started with letters, dots (.), ‘ ’ and ‘?’. If an identifier is prefixed with a ‘$’ then it indicate that it is an identifier not a reserved word. Maximum length of an identifier is 4095 characters. We can also use the name of a segment register as an instruction prefix: ✞ 1 es mov [bx],ax ; both are equal mov [es:bx],ax ; both are equal & it is recommended ✌ ✆ Unlike GAS assembler, register name e.g. eax, ebp, ebx, cr0 are not prefixed by a % sign. The Unix object formats, and the bin object format, all support the standardized section names .text, .data and .bss for the code, data and uninitializeddata sections. The A NASM file is divided in following sections. ✞ org 100h 2 section .text start: 4 ; put your code here section .data 6 ; put data items here section .bss 8 ; put uninitialized data here ✌ ✆ This file is compiled with following NASM command. ✞ nasm <.asm file > f b i n o <out file name > ✌ ✆ A simple helloworld.asm program for Window OS is given below: ✞ 1 section .data msg db ’Hello World!’, 0Ah ; End with line feed character 3 section .text
  • 37. 2.1. NASM 37 5 global _start ; Entry point in Windows OS 7 _start: ; Window OS convention mov edx , 13 ; Number of bytes to write 9 mov ecx , msg ; Copy msg memory address into ecx mov ebx , 1 ; Write to the STDOUT file 11 mov eax , 4 ; invoke SYS_WRITE (kernel opcode 4) int 80h 13 mov ebx , 0 ; return 0 on exit - ’No Errors ’ mov eax , 1 ; invoke SYS_EXIT (kernel opcode 1) 15 int 80h ✌ ✆ In Linux system, underscore before labels is removed. Compile this file in NASM with Windows OS using following command and run to see desired result. ✞ 1 nasm -f elf helloworld .asm ld -m elf_i386 helloworld .o -o helloworld 3 ./ helloworld ✌ ✆ The output is ✞ Hello World! ✌ ✆ 2.1.9 Calling External Functions Sometime assembly language functions are linked with C to call C functions from assembly codes. To do so, we should have familiar with gcc calling conventions. In assembly language, parameters are pushed on the stack, right ot left and are removed by the caller after the call. After the parameters are pushed, the call instruction is made, so when the called function gets control, the return address is at [esp], the first parameter is at [esp+4], etc. It is the caller’s responsibility to remove the parameters from the stack after a function call in stdcall or cdecl calling conventions. rAdd of old esp (0xff00ff00) Addr of para (0xffeeff00) rAdd of printf (0xfbabff00) esp esp+4 Stack High Memory Low Memory Values of registers ebx, esi, edi, ebp, ds, es, ss, must be saved before the calling of the function. A function that returns an integer value should return it in eax and a floating point value should be returned on the fpu stack top. push instruction adds the value in stack from high memory to low memory, i.e. in reverse memory order. See the following codes. ✞ 1 global main extern printf 3 section .text
  • 38. 38 C in ASM main : 5 push msg call printf ; Calling C printf function 7 add esp , 4 ; Set the location of esp to its ; old location 9 ret msg: 11 db ’Hello , World’, 10, 0 ✌ ✆ When the program being executed and on execution of each opcode, stack pointer is incrases by one. Assume, when subroutine main was being executed, esp pointed to memory containing the return address from subroutine. Let it is current location of esp and it is shown in the following figure. rAdd of old esp (0xff00ff00) esp Stack High Memory Low Memory At the execution of instruction ✞ 1 push msg ✌ ✆ message is stored in the memory and address of first character of the message string is stored in the stack. Now, esp pointed to the current location of stack, which is at next four bytes (i.e. [esp+4]) for 32 bits system. In 32 bits system, 4 bytes are sufficient to address all possible memory locations. rAdd of old esp (0xff00ff00) Add of msg (0xffeeff00) esp Stack High Memory Low Memory On execution of ✞ 1 call printf ✌ ✆ return address of printf is stored in the stack and esp pointed to this current stack location. rAdd of old esp (0xff00ff00) Add of msg (0xffeeff00) rAdd of printf (0xffeeffdd) esp Stack High Memory Low Memory
  • 39. 2.1. NASM 39 While execution of printf, it moves backward (i.e. esp is decremented) in stack and accepts required number of values from the memory addressed by the esp and gives desired result. Due to call of printf current location of esp is changed as shown below: rAdd of old esp (0xff00ff00) Add of msg (0xffeeff00) rAdd of printf (0xffeeffdd) esp Stack High Memory Low Memory Now, the actual position of the esp is changed, so to put the esp at its original location on the stack, we increase the esp by equal number of bytes it was decremented and here, it is 4 bytes (i.e. increase the location of esp from low memory to high memory). So, instruction ✞ 1 add esp , 4 ✌ ✆ sets the esp to its old location on the stack. Note that, when element is added in stack, position of esp changes from high memory to low memory. This is why, to set the esp at its old position, esp is moved towards higher memory by adding suitable number of bytes as shown in the following figure. rAdd of old esp (0xff00ff00) Add of msg (0xffeeff00) rAdd of printf (0xffeeffdd) esp+4 Stack High Memory Low Memory Now at last, ret instruction is executed. After execution of ret control is return to original subroutine. Stack values remain in stack and they can be accessed by changing position of esp suitably. And current memory is set as current location of esp. rAdd of old esp (0xff00ff00) Add of msg (0xffeeff00) rAdd of printf (0xffeeffdd) esp Stack High Memory Low Memory Compile it with following commands and run. You will get desired result. ✞ 1 nasm -felf a.asm gcc a.o -o a 3 ./a ✌ ✆
  • 40. 40 C in ASM esp esp-4 rAddr of old esp Addr of msg espPtr rAddr of old esp Addr of msg rAddr of printf High to Low In above figure, the stack memory is shown before calling of printf (left) and position of esp pointer after calling of printf (right). To put the esp i.e. stack pointer at the top of stack, it should be incremented by 4 bytes. And it is done by add instruction as shown in the above example. To show that stack values are not removed when we change the location of esp, see the following example. ✞ 1 global main extern printf 3 section .text main : 5 push msg call printf ; Calling C printf function 7 add esp , 4 ; Set the location of esp to its ; old location 9 sub esp , 4 ; Set esp to location of msg address call printf ; Calling C printf function 11 add esp , 4 ; Set the location of esp to its ; old location 13 ret msg: 15 db ’Hello , World’, 10, 0 ✌ ✆ When compiled and run, we will find the desired result. ✞ Hello , World Hello , World ✌ ✆ In case of return of numeric value, the above code shall be modifed accordingly. ✞ global main 2 extern printf section .text 4 main : mov ecx , 40 ; Original value to ecx 6 push ecx ; Store original value ;sequencial stack values for printf 8 push ecx ;L1 Copy printing value in stack push format ;L2 Copy printf format in stack 10 call printf ;L3 Call printf function of C ; 12 add esp , 8 ; Set esp at esp+8 location from ; current esp pointer location and 14 ; remove all elements at low memory side pop ecx ; Restore value of ecx 16 ret
  • 41. 2.1. NASM 41 format: 18 db ’%10d’, 0 ✌ ✆ in above example, two parameters are pushed into the stack. First is value to be printed (L1), second is format (L2) and then printf is called (L3), which is equivalent to ✞ printf("%10d",<ecx >); ✌ ✆ At call of printf function, required format and values being started reading backward through stack addresses. After reading required parameters, printf is executed, result is stored in memory and its address is pushed at the top of the stack. esp esp-4 esp-8 esp-12 rAddr of old esp Addr of value 40 Addr of value 40 Addr of format espPtr rAddr of old esp Addr of value 40 Addr of value 40 Addr of format rAddr of printf High to Low Memory In above figure, the stack memory is shown before calling of printf (left) and position of esp pointer after calling of printf (right). To put the esp i.e. stack pointer at the top of stack, it should be incremented by 8 bytes. And it is done by add instruction as shown in the above example. There is also interrupt mode of printing string in the console. See the following example. ✞ 1 section .data str: db "Hello , how are you? ", 100, 0 3 section .text 5 global main 7 main : 9 mov eax , 4 ; EAX=4 & EBX=1 (SYS_WRITE kernel mode ) mov ebx , 1 ; write to STDOUT file 11 mov ecx , str ; string at destination mov edx , 100 ; Length of string 13 int 80h ; interrupt 15 mov eax , 1 ; Return mov ebx , 0 ; Return code 17 int 80h ; interrupt ✌ ✆ 2.1.10 Uers’s Input In Linux Kernel, the combination of eax and ebx register allow read and write of the data from the stream or into the stream respectively. For example, setting eax as 3 and ebx
  • 42. 42 C in ASM as 0 results System Read Kernel Mode and system reades data from the input stream. Similarly, setting eas as 4 and ebx as 1 results System Write Kernel Mode and system writes data into the output stream. See the example below: ✞ 1 section .data str: db 100 ; Allocate buffer of 100 bytes 3 section .text 5 global main 7 main : 9 mov eax , 3 ; EAX=3 & EBX=0 (SYS_READ kernel mode ) mov ebx , 0 ; write to STDIN file 11 mov ecx , str ; copy string at destination mov edx , 100 ; Length of string 13 int 80h ; interrupt to end 15 mov eax , 4 ; EAX=4 & EBX=1 (SYS_WRITE kernel mode ) mov ebx , 1 ; write to STDOUT file 17 mov ecx , str ; string at destination mov edx , 100 ; Length of string 19 int 80h ; interrupt to end 21 mov eax , 1 ; Return mov ebx , 0 ; Return code 23 int 80h ; interrupt to end ✌ ✆ 2.1.11 Macros Assemblers are line oriented, i.e. they codes line-by-line. This is why, NASM has single line macros as well as multiline macros. In NASM, single line macros are declared with define keyword as given below: ✞ 1 %define myVar mov ✌ ✆ Here, ‘myVar’ is macro name and mov is its value. See the example below, in which ‘msg’ label is redefined to ‘mymsg’ by using %define directive. ✞ 1 global main extern printf 3 section .text %define mymsg msg 5 main : push mymsg 7 call printf ; calling C printf function add esp , 4 ; Set the location of esp to 9 ; its old location and remove ; all stack elements at low 11 ; memory side
  • 43. 2.1. NASM 43 ret 13 msg: db ’Hello , World’, 10, 0 ✌ ✆ Multi-line NASM macros are declared as given below: ✞ %macro <macro name > <n> 2 <codes > %endmacro ✌ ✆ Here, ‘n’ is number of possible arguments those shall be passed to this macro. Macroname may or may not be reserved keywords. Arguments may be zero or more than one. In case of more than one parameters, each sequential parameters are passed to placeholder by %1, %2 etc. Multi-line macros, like single-line macros, are case-sensitive, unless you define them using the alternative directive %imacro. Macro names may or may not a machine instruction. In case of macro name is machine instruction, then it will overload to the previously defined macro. ✞ 1 extern printf %macro myMacro 1 ; user ’s print macro 3 section .data mystr db %1,0 ; %1 is first parameter in macro call 5 section .text ; pushed onto stack backwards 7 push dword [c] ; int c push dword [b] ; int b 9 push dword [a] ; int a push dword mystr ; users string 11 push dword fmt ; address of format string call printf ; Call C function 13 add esp ,20 ; Set esp at its old location ; and remove elements at low 15 ; memory side %endmacro 17 section .data ; preset constants , writeable 19 fmt: db "%s, a=%d, b=%d, c=%d" ,10,0 a: dd 5 21 b: dd 6 c: dd 0 23 section .text ; instructions , code segment 25 global main ; gcc standard linking label main : ; gcc entry point -> "main " 27 mov eax ,[a] ; load a add eax ,[b] ; add b 29 mov [c],eax ; copy a+b into c myMacro "c=a+b" ; call user ’s printing macro 31 mov eax ,0 ; exit code , 0= normal 33 ret ; main return to operating system ✌ ✆
  • 44. 44 C in ASM Compile it with following commands and run. You will get desired result. ✞ 1 nasm -felf a.asm gcc a.o -o a 3 ./a ✌ ✆ The output of above code is ✞ c+a+b, a=5, b=6, c=11 ✌ ✆ NASM allows to define labels within a multi-line macro definition in such a way as to make them local to the macro call. To do this, label is prefixed by %%. See the structure as given below: ✞ 1 %macro myMacro 0 jnz %% mySkip 3 ret %% mySkip: 5 %endmacro ✌ ✆ Every time we call this macro, NASM make up a different ‘real’ name to substitute for the label%%mySkip. Label names should not be started with ‘@’ as it is used by NASM to declared macro-local lebels by own. Sometime, a macro is passed comma separated string whose one or two comma separated strings from the front are parameters and rest are data string. At this case, greedy macro is more useful. ✞ 1 %macro myMacro 2+ %% str: db %2 3 %% endstr: mov dx ,%% str 5 mov bx ,%1 %endmacro ✌ ✆ Here, ‘2+’ represents two arguments to this macro in which second is expanded greedy macro. In NASM greedy macro is indicated by ‘+’ sign after the parameter count on the macro line. When this macro is called with following command ✞ myMacro 10,"my string" ,120,52 ✌ ✆ Then ‘%1’ placeholder shall be assigned only value 10 and rest of the string is placed at the placeholder ‘%2’. ✞ 1 extern printf %macro myMacro 2+ ; user ’s greedy print macro 3 section .data myFstr db %1,0 ; %1 is first parameter 5 mySstr db %2,0 ; %2 is rest of parameters section .text 7 ; pushed onto stack backwards push mySstr ; rest of string 9 push myFstr ; first string
  • 45. 2.1. NASM 45 push dword fmt ; address of format string 11 call printf ; Call C function add esp ,12 ; Set esp at its old location 13 ; and remove all elements at ; low memory side 15 %endmacro section .data ; preset constants , writeable 17 fmt: db "%s, %s" ,10,0 19 section .text ; instructions , code segment global main ; for gcc standard linking 21 main : ; label "main " ; call user ’s printing macro 23 myMacro "print","This is string No.","3" 25 mov eax ,0 ; exit code , 0= normal ret ✌ ✆ Compile it with following commands and run. You will get desired result. ✞ root@box$ nasm -felf a.asm 2 root@box$ gcc a.o -o a root@box$ ./a ✌ ✆ The output of above code is ✞ print , This is string No .3 ✌ ✆ NASM also allows to expand range parameters via special constructions as shown below or example ✞ 1 %macro myRange 1-* db %{3:5} ; Arguments from 3rd to 5th parameters 3 %endmacro ✌ ✆ Range values may be positive or negative values but not zero. The range is moved from first range value to second range value either in increasing order or in decreasing order, depends which is greater. If this macro is called with instruction ✞ 1 myRange 1,2,3,4,5,6 ✌ ✆ Then output shall be only 3,4,5. NASM also allows to define a multi-line macro with a range of allowable parameter counts. So, for example: ✞ 1 %macro dieMacro 0-1 "Exiting due to error." <codes > 3 %endmacro ✌ ✆ If this macro is called with less number of required arguments or more then it show error before exiting from the macro.
  • 46. 46 C in ASM There are several inbuilt NASM macros which are used explicitely. They are %rotate for rotate parameter, %if-%elif-%else. Each %if condition should be closed with %endif macro. %ifdef is used to check whether a parameter is already defined or not and it should be closed with %endif macro. %ifmacro is considered true if defining a macro with the given name and number of arguments would cause a definitions conflict. %ifnum tests for the token being a numeric constant, %ifstr tests for it being a string. 2.1.12 Executing Command The EXEC family of functions replace the currently running process with a new process, that executes the specified command when calling it. We will be using the SYS EXECVE function to replace our program’s running process with a new process that will be exe- cuted. The first argument is a string containing the command to execute, then an array of arguments is to pass to that command and then another array of environment vari- ables that the new process will use. Both the command arguments and the environment arguments need to be passed as an array of pointers and then passed to SYS EXECVE. We call the function and the process is replaced by our command and output is returned to the terminal. ✞ 1 SECTION .data command db ’/bin/echo ’, 0h ; command to execute 3 arg1 db ’Hello World!’, 0h arguments dd command 5 dd arg1 ; arguments to pass to commandline dd 0h ; end the struct 7 env dd 0h ; arguments to pass as ; environment variables 9 SECTION .text global main 11 main : mov edx , env ; address of environment variables 13 mov ecx , arguments ; address of the arguments ; to pass to commandline 15 mov ebx , command ; address of the file to execute mov eax , 11 ; invoke SYS_EXECVE (kernel opcode 11) 17 int 80h ✌ ✆ 2.2 Link ASM with C First we shall write a .asm program which has a user defined function that shall be called from C by linking it. See the following example, in a user defined ‘myFirstAsm’ is defined to print string ‘Hello, world!’. ✞ 1 section .data hello: db ’Hello , world!’, 10 3 section .text 5 global myFirstASM
  • 47. 2.2. LINK ASM WITH C 47 7 myFirstASM : mov eax , 4 ; Leave space on stack for 9 ; local variable "myFirstASM " mov ebx , 1 11 mov ecx , hello mov edx , 13 13 int 80h ret ✌ ✆ Compile above program for 32 bit executable and linkable format (elf32) by using following command. ✞ nasm -f elf32 myFirstAsm.asm -o myFirstAsm.o ✌ ✆ Write a C program using extern keyword to access the ‘myFirstASM’ function as compiled above. ✞ 1 #include <stdio.h> 3 int main (int argc , char *argv []) { extern myFirstASM (); 5 myFirstASM (); } ✌ ✆ Now compile it with gcc using following command. ✞ gcc myFirstAsm .c myFirstAsm .o -o hello 2 ./ hello ✌ ✆ you will get the desired output. ASM functions can be called with input values from C programms too. See the following codes. The codes of add.asm file is given below: ✞ section .text 2 global myAsmAdd myAsmAdd : 4 push ebp ; Save the prior Base Pointer value mov ebp , esp ; Copy Stock Pointer into Base 6 ; Pointer [ebp +0] Space for old ; ebp value [ebp +4] Space for 8 ; return address mov eax , [ebp +8] ; Base Index Addressing. 10 ; Get First Input Value add eax , [ebp +12] ; Get Second input Value 12 pop ebp ; Return Output ret ✌ ✆ The codes of addc.c file is given below: ✞ 1 #include <stdio.h> /* Function , written in Assembly Language . */
  • 48. 48 C in ASM 3 int myAsmAdd (int , int); int main (void ) { 5 int a, b, ans; printf("Enter a, b: "); 7 scanf(" %i %i", &a, &b); ans = myAsmAdd (a, b); 9 printf("%dn", ans); return 0; 11 } ✌ ✆ Compile above program as given commands and run them. Your shall get desired result. ✞ 1 root@box$ gcc -Wall -c addc.c -o addc.o root@box$ nasm -f coff add.asm 3 root@box$ gcc -o add addc.o add.o root@box$ ./add ✌ ✆ If there is error in compilation of assembly file, then use following command. ✞ root@box$ nasm -f elf32 add.asm ✌ ✆ We can also specify the data variable names or function names written in the assembly code and being called for a variable or for a C function by using asm (or asm ) keyword after the declarator. We should be careful while choosing assembler names as they do not conflict with any other assembler symbols, or reference registers. ✞ 1 char *chello asm ("hello"); ✌ ✆ Now we can print the string assigned to “hello” in assembly code from the C codes directly as ✞ 1 #include <stdio.h> char *chello asm ("hello"); 3 int main (void ) { printf("%s", chello); 5 return 0; } ✌ ✆ Similarly, we can specify an assembly function for C codes as ✞ #include <stdio.h> 2 /* myAsmAdd , written in Assembly Language . */ int cAdd (int , int) asm("myAsmAdd "); 4 int main (void ) { int a, b, ans; 6 printf("Enter a, b: "); scanf(" %i %i", &a, &b); 8 ans = cAdd (a, b); printf("%dn", ans); 10 return 0; } ✌ ✆
  • 49. 2.2. LINK ASM WITH C 49 Compile above program as given commands and run them. Your shall get desired result. ✞ 1 root@box$ gcc -Wall -c addc.c -o addc.o root@box$ nasm -f elf32 add.asm 3 root@box$ gcc -o add addc.o add.o root@box$ ./add ✌ ✆