Intel’s ‘cmpxchg’ instructionSlide 2The x86 ‘system’ registersHow often is ‘cmpxchg’ used?Intel’s documentationExample: ‘cmpxchg’Instruction format‘effects’ and ‘affects’‘cmpxchg’ descriptionAn instruction-instanceSlide 11The ‘preparation’ stepsThe ‘cmos_lock’ variableThe ‘most likely’ senarioThe ‘busy-wait’ loopBusy-waiting will be briefThe ‘less likely’ caseflowchart‘btr’/’bts’ versus ‘cmpxchg’In-class exercise #1EFLAGSSlide 22Intel’s ‘cmpxchg’ instructionHow does the Linux kernel’s ‘cmos_lock’ mechanism work?Review of the i386 registersEAXEBXECXEDXESIEDIEBPESPGeneral Registers (32-bits)CSDSESFSGSSSSegment Registers (16-bits)EIPEFLAGSProgram Control and Status Registers (32 bits)The x86 ‘system’ registersCR0CR1CR2CR3CR4CR5CR6CR7Control Registers (32-bits)means ‘unimplemented’DR0DR1DR2DR3DR4 Debug Registers (32-bits)DR5DR6DR7LDTRTRGDTRIDTR(16-bits)(48-bits)How often is ‘cmpxchg’ used?$ cat vmlinux.asm | grep cmpxchgc01046de: f0 0f b1 15 3c 99 30 lock cmpxchg %edx,0xc030993cc0105591: f0 0f b1 15 3c 99 30 lock cmpxchg %edx,0xc030993cc01055d9: f0 0f b1 15 3c 99 30 lock cmpxchg %edx,0xc030993cc010b895: f0 0f b1 11 lock cmpxchg %edx,(%ecx)c010b949: f0 0f b1 0b lock cmpxchg %ecx,(%ebx)c0129a9f: f0 0f b1 0b lock cmpxchg %ecx,(%ebx)c0129acf: f0 0f b1 0b lock cmpxchg %ecx,(%ebx)c012d377: f0 0f b1 0e lock cmpxchg %ecx,(%esi)c012d41a: f0 0f b1 0e lock cmpxchg %ecx,(%esi)c012d968: f0 0f b1 16 lock cmpxchg %edx,(%esi)c012e568: f0 0f b1 2e lock cmpxchg %ebp,(%esi)c012e57a: f0 0f b1 2e lock cmpxchg %ebp,(%esi)c012e58a: f0 0f b1 2e lock cmpxchg %ebp,(%esi)c012e83f: f0 0f b1 13 lock cmpxchg %edx,(%ebx)c012e931: f0 0f b1 0a lock cmpxchg %ecx,(%edx)c012ea94: f0 0f b1 11 lock cmpxchg %edx,(%ecx)c012ecf4: f0 0f b1 13 lock cmpxchg %edx,(%ebx)c012f08e: f0 0f b1 4b 18 lock cmpxchg %ecx,0x18(%ebx)c012f163: f0 0f b1 11 lock cmpxchg %edx,(%ecx)c013cb60: f0 0f b1 0e lock cmpxchg %ecx,(%esi)c0148b3c: f0 0f b1 29 lock cmpxchg %ebp,(%ecx)c0150d0f: f0 0f b1 3b lock cmpxchg %edi,(%ebx)c0150d87: f0 0f b1 31 lock cmpxchg %esi,(%ecx)c0199c5e: f0 0f b1 0b lock cmpxchg %ecx,(%ebx)c024b06f: f0 0f b1 0b lock cmpxchg %ecx,(%ebx)c024b2fe: f0 0f b1 51 18 lock cmpxchg %edx,0x18(%ecx)c024b321: f0 0f b1 51 18 lock cmpxchg %edx,0x18(%ecx)c024b34b: f0 0f b1 4b 18 lock cmpxchg %ecx,0x18(%ebx)c024b960: f0 0f b1 53 18 lock cmpxchg %edx,0x18(%ebx)Here’s the occurrence that we studied in the ‘rtc_cmos_read()’ kernel-function……plus 28 other times!Intel’s documentation•You can find out what any of the Intel x86 instructions does by consulting the official software developer’s manual, online at:http://www.intel.com/products/processor/manuals/index.htm•Our course-webpage has a link to this site that you can just click (under ‘Resources’)•The instruction-set reference is two parts:–Volume 2A: for opcodes A through M–Volume 2B: for opcodes N through ZExample: ‘cmpxchg’•Operation of the ‘cmpxchg’ instruction is described (on 3 pages) in Volume 2A•There’s an English-sentence description, and also a description in ‘pseudo-code’•You probably do not want to print out this complete volume (.pdf) – over 700 pages!•(You could order a printed copy from Intel)Instruction format•Intel’s assembly language syntax differs from the GNU/Linux syntax (known as ‘AT&T syntax’ with roots in UNIX history) •When AT&T syntax is used, the ‘cmpxchg’ instruction has this layout:[lock] cmpxchg reg, reg/mem optional ‘prefix’ (used for SMP) mnemonic opcode source operand destination operand‘effects’ and ‘affects’•According to Intel’s manual, the ‘cmpxchg’ instruction also uses two ‘implicit’ operands (i.e., operands not mentioned in the instruction) –The CPU’s accumulator register–The CPU’s EFLAGS register•The accumulator-register (EAX) is both a source-operand and a destination-operand•The six status-bits in the EFLAGS register will get modified, as a ‘side-effect’ this instruction‘cmpxchg’ description •This instruction compares the accumulator with the destination-operand (so the ZF-bit in EFLAGS gets assigned accordingly)•Then:–If (accumulator == destination){ ZF 1; destination source; }–If (accumulator != destination){ ZF 0; accumulator destination; }An instruction-instance•In our recent disassembly of Linux’s kernel function ‘rtc_cmos_read()’, this ‘cmpxchg’ instruction-instance was used: lock cmpxchg %edx, cmos_lock prefix opcode source-operand destination-operand Note: Keep in mind that the accumulator %eax will affect what happens! So we need to consider this instruction within it’s surrounding contextThe complete functionc0105574 <rtc_cmos_read>:c0105574: 53 push %ebxc0105575: 9c pushfc0105576: 5b pop %ebxc0105577: fa clic0105578: 64 8b 15 08 20 30 c0 mov %fs:0xc0302008,%edxc010557f: 0f b6 c8 movzbl %al,%ecxc0105582: 42 inc %edxc0105583: c1 e2 08 shl $0x8,%edxc0105586: 09 ca or %ecx,%edxc0105588: a1 3c 99 30 c0 mov 0xc030993c,%eaxc010558d: 85 c0 test %eax,%eaxc010558f: 75 f7 jne c0105588 <rtc_cmos_read+0x14>c0105591: f0 0f b1 15 3c 99 30 lock cmpxchg %edx,0xc030993cc0105598: c0c0105599: 85 c0 test %eax,%eaxc010559b: 75 eb jne c0105588 <rtc_cmos_read+0x14>c010559d: 88 c8 mov %cl,%alc010559f: e6 70 out %al,$0x70c01055a1: e6 80 out %al,$0x80c01055a3: e4 71 in $0x71,%alc01055a5: e6 80 out %al,$0x80c01055a7: c7 05 3c 99 30 c0 00
View Full Document