Comparisons
Control structures decide what to do based on comparisons of data. In assembly, the result of a comparison is stored in the FLAGS register to be38 . BASIC ASSEMBLY LANGUAGE used later. The 80x86 provides the CMP instruction to perform comparisons.The FLAGS register is set based on the difference of the two operands of the CMP instruction. The operands are subtracted and the FLAGS are set based on the result, but the result is not stored anywhere. If you need the result use the SUB instead of the CMP instruction.For unsigned integers, there are two flags (bits in the FLAGS register) that are important: the zero (ZF) and carry (CF) flags. The zero flag is set (1) if the resulting difference would be zero. The carry flag is used as a borrow flag for subtraction. Consider a comparison like:
cmp vleft, vright
The difference of vleft - vright is computed and the flags are set accord-ingly. If the difference of the of CMP is zero, vleft = vright, then ZF is set (i.e. 1) and the CF is unset (i.e. 0). If vleft > vright, then ZF is unset and CF is unset (no borrow). If vleft <>
is set (borrow).For signed integers, there are three flags that are important: the zero
(ZF) flag, the overflow (OF) flag and the sign (SF) flag. The overflow flag Why does SF = OF if
vleft > vright? If there is no overflow, then the difference will have the correct value and must
be non-negative. Thus,SF = OF = 0. However,if there is an overflow, the difference will not have the correct value (and in fact will be negative). Thus,SF = OF = 1.is set if the result of an operation overflows (or underflows). The sign flag is set if the result of an operation is negative. If vleft = vright, the ZF is set (just as for unsigned integers). If vleft > vright, ZF is unset and
SF = OF. If vleft < sf =" OF.">
Branch instructions
Branch instructions can transfer execution to arbitrary points of a program. In other words, they act like a goto. There are two types of branches:unconditional and conditional. An unconditional branch is just like a goto,it always makes the branch. A conditional branch may or may not make the branch depending on the flags in the FLAGS register. If a conditional branch does not make the branch, control passes to the next instruction. The JMP (short for jump) instruction makes unconditional branches. Its single argument is usually a code label to the instruction to branch to. The assembler or linker will replace the label with correct address of the instruction. This is another one of the tedious operations that the assembler does to make the programmer’s life easier. It is important to realize that the statement immediately after the JMP instruction will never be executed unless another instruction branches to it!
Simple Conditional Branches
JZ branches only if ZF is set
JNZ branches only if ZF is unset
JO branches only if OF is set
JNO branches only if OF is unset
JS branches only if SF is set
JNS branches only if SF is unset
JC branches only if CF is set
JNC branches only if CF is unset
JP branches only if PF is set
JNP branches only if PF is unset
There are several variations of the jump instruction: SHORT This jump is very limited in range. It can only move up or down 128 bytes in memory. The advantage of this type is that it uses less
memory than the others. It uses a single signed byte to store the displacement of the jump. The displacement is how many bytes to move ahead or behind. (The displacement is added to EIP). To specify a short jump, use the SHORT keyword immediately before the label in the JMP instruction.
NEAR This jump is the default type for both unconditional and conditional branches, it can be used to jump to any location in a segment. Actually, the 80386 supports two types of near jumps. One uses two bytes for the displacement. This allows one to move up or down roughly 32,000 bytes. The other type uses four bytes for the displacement, which of course allows one to move to any location in the code segment. The four byte type is the default in 386 protected mode. The two byte type can be specified by putting the WORD keyword
before the label in the JMP instruction.
FAR This jump allows control to move to another code segment. This is a very rare thing to do in 386 protected mode. Valid code labels follow the same rules as data labels. Code labels are defined by placing them in the code segment in front of the statement they label. A colon is placed at the end of the label at its point of definition. The
colon is not part of the name.
There are many different conditional branch instructions. They also take a code label as their single operand. The simplest ones just look at a single flag in the FLAGS register to determine whether to branch or not.See Table for a list of these instructions. (PF is the parity flag which
indicates the odd or evenness of the number of bits set in the lower 8-bits of the result.)
The following pseudo-code,
if ( EAX == 0 )
EBX = 1;
else
EBX = 2;
could be written in assembly as:
1 cmp eax, 0 ; set flags (ZF set if eax - 0 = 0)
2 jz thenblock ; if ZF is set branch to thenblock
3 mov ebx, 2 ; ELSE part of IF
4 jmp next ; jump over THEN part of IF
5 thenblock:
6 mov ebx, 1 ; THEN part of IF
7 next:
Other comparisons are not so easy using the conditional branches in Table To illustrate, consider the following pseudo-code:
if ( EAX >= 5 )
EBX = 1;
else
EBX = 2;
If EAX is greater than or equal to five, the ZF may be set or unset and SF will equal OF. Here is assembly code that tests for these conditions (assuming that EAX is signed):
1 cmp eax, 5
2 js signon ; goto signon if SF = 1
3 jo elseblock ; goto elseblock if OF = 1 and SF = 0
4 jmp thenblock ; goto thenblock if SF = 0 and OF = 0
5 signon:
6 jo thenblock ; goto thenblock if SF = 1 and OF = 1
7 elseblock:
8 mov ebx, 2
9 jmp next
10 thenblock:
11 mov ebx, 1
12 next:
The above code is very awkward. Fortunately, the 80x86 provides additional branch instructions to make these type of tests much easier. There are signed and unsigned versions of each. Table shows these instructions. The equal and not equal branches (JE and JNE) are the same for both signed and unsigned integers. (In fact, JE and JNE are really identical2.2.
Signed and Unsigned Comparison Instructions
JE branches if vleft = vright JE branches if vleft = vright
JNE branches if vleft = vright JNE branches if vleft = vright
JL, JNGE branches if vleft <>
JLE, JNG branches if vleft ≤ vright JBE, JNA branches if vleft ≤ vright
JG, JNLE branches if vleft > vright JA, JNBE branches if vleft > vright
JGE, JNL branches if vleft ≥ vright JAE, JNB branches if vleft ≥ vright
Signed Unsigned to JZ and JNZ, respectively.) Each of the other branch instructions have
two synonyms. For example, look at JL (jump less than) and JNGE (jump not greater than or equal to). These are the same instruction because: x < y ="⇒">
1 cmp eax, 5
2 jge thenblock
3 mov ebx, 2
4 jmp next
5 thenblock:
6 mov ebx, 1
7 next:
The loop instructions
The 80x86 provides several instructions designed to implement for -like loops. Each of these instructions takes a code label as its single operand. LOOP Decrements ECX, if ECX = 0, branches to label LOOPE, LOOPZ Decrements ECX (FLAGS register is not modified), if
ECX = 0 and ZF = 1, branches LOOPNE, LOOPNZ Decrements ECX (FLAGS unchanged), if ECX = 0 and ZF = 0, branches
The last two loop instructions are useful for sequential search loops.
The following pseudo-code:
sum = 0;
for ( i=10; i >0; i−− )
sum += i;
could be translated into assembly as:
1 mov eax, 0 ; eax is sum
2 mov ecx, 10 ; ecx is i
3 loop_start:
4 add eax, ecx
5 loop loop_start
Translating Standard Control Structures
This section looks at how the standard control structures of high level languages can be implemented in assembly language.
If statements
The following pseudo-code:
if ( condition )
then block ;
else
else block ;
could be implemented as:
1 ; code to set FLAGS
2 jxx else_block ; select xx so that branches if condition false
3 ; code for then block
4 jmp endif
5 else_block:
6 ; code for else block
7 endif:
If there is no else, then the else block branch can be replaced by a
branch to end if.
1 ; code to set FLAGS
2 jxx endif ; select xx so that branches if condition false
3 ; code for then block
4 endif
While loops
The while loop is a top tested loop:
while( condition ) {
body of loop;
}
This could be translated into:
1 while:
2 ; code to set FLAGS based on condition
3 jxx endwhile ; select xx so that branches if false
4 ; body of loop
5 jmp while
6 endwhile:
Do while loops
The do while loop is a bottom tested loop:
do {
body of loop;
} while( condition );
This could be translated into:
1 do:
2 ; body of loop
3 ; code to set FLAGS based on condition
4 jxx do ; select xx so that branches if true
Refrence - PC Assembly Language Paul A. Carter
This was great! Thanks!
ReplyDeleteIt is nice blog Thank you provide important information and i am searching for same information to save my time Data Science online Course India
ReplyDeleteGreeat blog you have
ReplyDelete