comp 2003: assembly language and digital logic
DESCRIPTION
COMP 2003: Assembly Language and Digital Logic. Chapter 2: Flags and Instructions Notes by Neil Dickson. More Common Instructions. sub dest , src ; dest -= src. and dest , src ; dest &= src. or dest , src ; dest |= src. xor dest , src ; dest ^= src. Examples of and/or/xor. - PowerPoint PPT PresentationTRANSCRIPT
COMP 2003:Assembly Language and Digital Logic
Chapter 2: Flags and InstructionsNotes by Neil Dickson
More Common Instructions
sub dest,src ;dest -= srcand dest,src ;dest &= srcor dest,src ;dest |= srcxor dest,src ;dest ^= src
Examples of and/or/xormov al,0E3h
and al,59h
or al,7Ah
xor al,26h
xor al,al
1 1 1 0 00 1 1al59h 0 1 0 1 01 0 1
0 1 0 0 00 0 1al7Ah 0 1 1 1 01 1 0
0 1 1 1 01 1 1al26h 0 0 1 0 10 1 0
0 1 0 1 11 0 1al
3 bits cleared
4 bits set
3 bits complemented
0 1 0 1 11 0 1al
0 0 0 0 00 0 0alall set bits complemented,
clearing them, so result is 0
Bit Shift Instructionsshl dest,imm ;dest <<= imm
shr dest,imm ;(unsigned)dest >>= imm
shr dest,cl ;(unsigned)dest >>= cl
shl dest,cl ;dest <<= cl
sar dest,imm ;(signed)dest >>= imm
sar dest,cl ;(signed)dest >>= cl
1 1 1 0 00 1 1 000Bit 0Bit 1Bit 2Bit 3Bit 4Bit 5Bit 6Bit 7
Shifting left 3 bits
;dest *= 2imm
;dest *= 2cl
;(unsigned)dest /= 2imm
;(unsigned)dest /= 2cl
;(signed)dest /= 2imm
;(signed)dest /= 2cl
mul & div (unsigned)
mul src8bit ;ax = al*src8bitmul src16bit ;dx:ax =
ax*src16bit mul src32bit ;edx:eax = eax*src32bit
div src8bit ;al = ax/src8bitdiv src16bit ;ax =
dx:ax/src16bit div src32bit ;eax = edx:eax/src32bit
Divide error if result doesn’t fit
not, neg, & xchg
not src ;src = ~src
neg src ;src = -src
xchg dest,src ;swap(dest,src)
Main Condition Flags
• Zero Flag: 1 if result is zero, else 0• Carry Flag: 1 if operation had unsigned
overflow (carry/borrow), else 0• Sign Flag: 1 if result is negative, else 0• Overflow Flag: 1 if operation had signed
overflow, else 0• Parity Flag: 1 if low byte of result has even
number of bits set, else 0
Compare / Test Instructions
cmp dest,src ;flags of dest-srctest dest,src ;flags of dest&src
NOTE: add, sub, and, or, xor, shl, shr, sar, mul, div, not, and neg also modify the flags based on their results, but cmp and test only modify the flags.
cmp Conditions
• Equal = Zero (ZF=1)• Not Equal = Not Zero (ZF=0)• Below = Carry (CF=1)• Not Below = Above or Equal = No Carry (CF=0)• Above = No Carry and Not Zero (CF=0 and ZF=0)• Not Above = Below or Equal = Carry or Zero (CF=1 or ZF=1)• Less (signed) = (it’s complicated)• Not Less (signed) = Greater or Equal (signed)• Greater (signed)• Not Greater (signed) = Less or Equal (signed)
je, jz
jne, jnz
jb, jc
jnb, jnc, jae
ja
jna, jbejl
jnl , jge
jg
jng , jle
sete, setz, cmove, cmovz
setne, setnz, cmovne,...
Other Conditions
• negative Sign (SF=1)• No negative Sign (SF=0)• Overflow (OF=1)• No Overflow (OF=0)• Parity = Parity Even (PF=1)• Not Parity = Parity Odd (PF=0)
js
jns
jo
jp, jpe
sets, cmovs
setns, cmovns
jno
jnp, jpo
Remember:
cmp = sub that only saves flags (ZF, CF, SF, OF) for comparing valuestest = and that only saves flags (ZF, SF; CF=0, OF=0) for checking whether certain bits are set
...
Example: Counting Set Bitscount = 0;for (int i=0;i<32;++i) { // for each bit i if (data & (1<<i)) { // if bit i is 1 ++count; // add 1 to count }}
edx = 0;cl = 0;do { if (eax & (1<<cl)) { ++edx; } ++cl;} while (cl<32);
edx = 0;cl = 0;NextBit: ebx = 1; ebx <<= cl; if ((eax & ebx)==0) goto BitIsZero; ++edx; BitIsZero: ++cl;if (cl<32) goto NextBit;
↓
→
Example: Counting Set Bitsedx = 0;cl = 0;NextBit: ebx = 1; ebx <<= cl; if ((eax & ebx)==0) goto BitIsZero; ++edx; BitIsZero: ++cl;if (cl<32) goto NextBit;
mov edx,0 mov cl,0NextBit: mov ebx,1 shl ebx,cl test eax,ebx jz BitIsZero add edx,1BitIsZero: add cl,1 cmp cl,32 jb NextBit
→ 1
1 After this test, the zero flag is set if the result of (eax&ebx) is 0, else zero flag is clear.
2
2 cmp dest,src followed by jb LineLabel means that the code jumps iff dest<src. The same order applies for other conditions (e.g. jae jumps iff dest>=src)
We can improve upon this!
Starting to Improve mov edx,0 mov cl,0NextBit: mov ebx,1 shl ebx,cl test eax,ebx jz BitIsZero add edx,1BitIsZero: add cl,1 cmp cl,32 jb NextBit
1
1 This bit mask in ebx gets recalculated from scratch every time, when each time the bit that’s 1 is just one bit to the left from last time.
mov edx,0 mov cl,0 mov ebx,1NextBit: test eax,ebx jz BitIsZero add edx,1BitIsZero: shl ebx,1 add cl,1 cmp cl,32 jb NextBit
2
2 cl is now only used to count the number of times that the loop occurs, so count down from 32 to 0 instead of up from 0 to 32 so that we can just check the zero flag to see if it’s zero yet.
mov edx,0 mov cl,32 mov ebx,1NextBit: test eax,ebx jz BitIsZero add edx,1BitIsZero: shl ebx,1 sub cl,1 jnz NextBit
Jumps if cl (the result of sub) isn’t zero yet.
Another Approach mov edx,0 ;count = 0NextBit: ;do { test eax,1 ; if (bit 0 of eax is set) { jz BitIsZero ; add edx,1 ; ++countBitIsZero: ; } shr eax,1 ; shift eax right to get a new bit 0 jnz NextBit ;} while (eax!=0)
1
1 The value of eax gets destroyed, so this may not be desired, but we could always mov it into another register beforehand.
2
2 This is the same as checking whether eax is odd, since in binary, odd numbers have a 1 in bit 0, and even numbers have a 0 in bit 0.
3
3 As mentioned before, this is the same as dividing eax by 2.
Went from 8 instructions in the loop down to 5, and <32 iterations if high bit of eax is clear