140 likes | 343 Views
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.
E N D
COMP 2003:Assembly Language and Digital Logic Chapter 2: Flags and Instructions Notes by Neil Dickson
More Common Instructions subdest,src;dest -= src anddest,src;dest &= src ordest,src;dest |= src xordest,src;dest ^= src
Examples of and/or/xor moval,0E3h andal,59h or al,7Ah xoral,26h xoral,al al 1 1 1 0 0 0 1 1 59h 0 1 0 1 1 0 0 1 al 0 1 0 0 0 0 0 1 3 bits cleared 7Ah 0 1 1 1 1 0 1 0 al 0 1 1 1 1 0 1 1 4 bits set 26h 0 0 1 0 0 1 1 0 al 0 1 0 1 1 1 0 1 3 bits complemented al 0 1 0 1 1 1 0 1 all set bits complemented, clearing them, so result is 0 al 0 0 0 0 0 0 0 0
Bit Shift Instructions ;dest *= 2imm shldest,imm;dest <<= imm shldest,cl;dest <<= cl ;dest *= 2cl shrdest,imm;(unsigned)dest >>= imm ;(unsigned)dest /= 2imm shrdest,cl;(unsigned)dest >>= cl ;(unsigned)dest /= 2cl sardest,imm;(signed)dest >>= imm ;(signed)dest /= 2imm sardest,cl;(signed)dest >>= cl ;(signed)dest /= 2cl Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 1 1 1 0 0 0 1 1 0 0 0 Shifting left 3 bits
mul & div (unsigned) mul src8bit ;ax = al*src8bit mul src16bit ;dx:ax = ax*src16bit mul src32bit ;edx:eax = eax*src32bit div src8bit ;al = ax/src8bit div 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 xchgdest,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 cmpdest,src;flags of dest-src testdest,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 testonly 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 sete, setz, cmove, cmovz jne, jnz setne, setnz, cmovne,... jb, jc jnb, jnc, jae ja jl jna, jbe jnl , jge jg jng , jle
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 sets, cmovs jns setns, cmovns jo ... jno jp, jpe jnp, jpo Remember: cmp = sub that only saves flags (ZF, CF, SF, OF) for comparing values test = and that only saves flags (ZF, SF; CF=0, OF=0) for checking whether certain bits are set
Example: Counting Set Bits count = 0; for (inti=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; NextBit: ebx = 1; ebx <<= cl; if ((eax & ebx)==0) gotoBitIsZero; ++edx; BitIsZero: ++cl; if (cl<32) gotoNextBit; edx = 0; cl = 0; do { if (eax & (1<<cl)) { ++edx; } ++cl; } while (cl<32); →
Example: Counting Set Bits edx = 0; cl = 0; NextBit: ebx = 1; ebx <<= cl; if ((eax & ebx)==0) gotoBitIsZero; ++edx; BitIsZero: ++cl; if (cl<32) gotoNextBit; movedx,0 movcl,0 NextBit: movebx,1 shlebx,cl testeax,ebx jzBitIsZero add edx,1 BitIsZero: addcl,1 cmpcl,32 jbNextBit → 1 2 1 After this test, the zero flag is set if the result of (eax&ebx) is 0, else zero flag is clear. 2 cmp dest,src followed by jbLineLabel 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 movedx,0 movcl,0 NextBit: movebx,1 shlebx,cl testeax,ebx jzBitIsZero add edx,1 BitIsZero: addcl,1 cmpcl,32 jbNextBit movedx,0 movcl,0 movebx,1 NextBit: testeax,ebx jzBitIsZero add edx,1 BitIsZero: shlebx,1 addcl,1 cmpcl,32 jbNextBit movedx,0 movcl,32 movebx,1 NextBit: testeax,ebx jzBitIsZero add edx,1 BitIsZero: shlebx,1 subcl,1 jnzNextBit 1 2 Jumps if cl (the result of sub) isn’t zero yet. 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. 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.
Another Approach movedx,0 ;count = 0 NextBit: ;do { testeax,1 ; if (bit 0 of eax is set) { jzBitIsZero; add edx,1 ; ++count BitIsZero: ; } shreax,1 ; shift eax right to get a new bit 0 jnzNextBit;} while (eax!=0) 2 1 3 1 The value of eax gets destroyed, so this may not be desired, but we could always mov it into another register beforehand. 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 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