การกระโดดและการวนรอบ
คำสั่งกระโดด Jxx label คำสั่งกระโดดมี 3 รูปแบบ คำสั่งกระโดดแบบไม่มีเงื่อนไข คำสั่งกระโดดแบบมีเงื่อนไขตามแฟล็กซ์ คำสั่งกระโดดแบบมีเงื่อนไขตามค่าในรีจิสเตอร์ Jxx label MOV AX, 01H ADD AX, BX CMP AX, 0 JZ TRUE JNZ FALSE TRUE : INC AX FALSE : INC CX AX := BX + 1; IF AX = 0 THEN AX:=AX+1; CX := CX + 1;
คำสั่งกระโดด นิยมใช้คู่กับคำสั่งทางคณิตศาสตร์โดยเฉพาะคำสั่งเปรียบเทียบ (CMP) ข้อมูลที่นำมาเปรียบเทียบเป็นข้อมูลชนิดตัวเลขเสมอ แต่คำสั่งกระโดดรองรับได้ทั้งตัวเลขแบบคิดเครื่องหมายและไม่คิดเครื่องหมาย การกระโดดทุกครั้งสามารถกระโดดไปที่เลเบลเท่านั้น ไม่สามารถกระโดดไปที่หมายเลขบรรทัดได้ การกำหนดเลเบลต้องกำหนดที่ต้นบรรทัดเท่านั้น
คำสั่งการกระโดดเบื้องต้น JMP <เลเบล> กระโดดข้ามไปที่ <เลเบล> อย่างไม่มีเงื่อนไข JZ (JE) <เลเบล> กระโดดข้ามไปที่ <เลเบล> เมื่อผลของคำสั่งทางคณิตศาสตร์ล่าสุดที่ผ่านมาเป็นศูนย์ JNZ (JNE) <เลเบล> กระโดดข้ามไปที่ <เลเบล> เมื่อผลของคำสั่งทางคณิตศาสตร์ล่าสุดที่ผ่านมาไม่เป็นศูนย์
คำสั่งกระโดด (ตัวเลขไม่มีเครื่องหมาย) เงื่อนไขการกระโดด แฟล็กทดสอบ JA (JNBE) Above CF = 0 , ZF = 0 JB (JNAE) Below CF = 1 , ZF = 0 JAE (JNB) Above or Equal Zero CF = 0 , ZF = 1 JBE (JNA) Below or Equal Zero CF = 1 , ZF = 1
คำสั่งกระโดด (ตัวเลขมีเครื่องหมาย) เงื่อนไขการกระโดด แฟล็กทดสอบ JG (JNLE) Greater OF = SF , ZF = 0 JL (JNGE) Less OF ≠ SF , ZF = 0 JGE (JNL) Greater or Equal Zero OF = SF , ZF = 1 JLE (JNG) Less or Equal Zero OF ≠ SF , ZF = 1
คำสั่งกระโดด (ตามแฟล็กซ์และรีจิสเตอร์) การกระโดด ความหมาย แฟล็กทดสอบ JNC No Carry CF = 0 JO Overflow OF =1 JNO Not Overflow OF =0 JS Sign SF = 1 JNS No Sign SF = 0 JPO (JNP) Parity odd PF = 0 JPE (JP) Parity Even PF = 1 JCXZ CX = 0 none
ตัวอย่างการใช้คำสั่งกระโดด cmp ah,10 jz lab1 mov bx,2 lab1: add cx,10 ;เปรียบเทียบ ah กับ 10 ;ถ้าเท่ากันให้กระโดดไปที่ lab1 Ex#1 EX#2 cmp ah,10 jge tenup add dl,’0’ jmp endif tenup: add dl,’A’ endif: ;เปรียบเทียบ ah กับ 10 ถ้ามากกว่า ;หรือเท่ากับให้กระโดดไปที่ lab1 ;ปรับค่า dl ;กระโดดไปที่ endif
การประยุกต์คำสั่งกระโดด Repeat Statement; Until condition ; While condition do statement ; condition False True Statement condition False True Statement
การประยุกต์คำสั่งกระโดด (repeat) Pascal Language Assembly Language ax := 10; repeat ax := ax-1; bx := bx+1; cx := ax-bx; until ax = 0 ; dx := dx + 10; mov ax,10 repeat: dec ax inc bx sub ax,bx mov cx,ax cmp ax,0 jnz repeat
การประยุกต์คำสั่งกระโดด (while) Pascal Language Assembly Language while: cmp ax,128h jge endwhile add ax,bx inc bx jmp while endwhile: dec cx while ax < 28h do begin ax := ax+bx ; bx := bx+1 ; end; cx := cx-1 ;
แบบฝึกหัด จงเขียนคำสั่งในการบวกตัวเลขจาก 1 ถึง 50 และเก็บค่าไว้ใน AX จงเขียนคำสั่งในการหา หรม. ของ AX และ BX กำหนดให้เป็นตัวเลขไม่คิดเครื่องหมาย Loop : CMP AX , BX JB Notswap MOV CX , AX MOV AX , BX MOV BX , CX Notswap : SUB BX , AX JNZ Loop
คำสั่งวนรอบ LOOP label คำสั่งวนรอบเป็นคำสั่งที่ใช้ในการกระทำซ้ำ โดยใช้รีจิสเตอร์ CX (Counter Register) ในการนับจำนวนครั้งของการกระทำซ้ำ รูปแบบ LOOP label คำสั่งในกลุ่มนี้คือ LOOP : คำสั่งที่พิจารณาค่าของ CX อย่างเดียว LOOPZ , LOOPNZ : พิจารณาแฟล็กร่วมด้วย
คำสั่งวนรอบ LOOP การทำงานของคำสั่ง LOOP ลดค่าของ CX ลงหนึ่ง โดยไม่กระทบแฟล็ก ถ้า CX ยังมีค่ามากกว่าศูนย์ กระโดดไปทำงานที่เลเบลที่ระบุ คำสั่ง LOOP มีการทำงานเทียบเท่ากับ DEC CX JNZ label แต่ไม่มีการกระทบแฟล็ก
ตัวอย่างการใช้คำสั่งวนรอบ EX mov cx,50h mov bl,1 mov dx,0 addnumber: add dl,bl adc dh,0 inc bl loop addnumber ; ทำซ้ำ 50 ครั้ง ; เริ่มที่ 1 ; ค่าเริ่มต้น = 0 ; บวก 8 บิตล่าง ; บวกตัวทด ; ทำซ้ำ
คำสั่ง LOOPZ และ LOOPNZ คำสั่ง LOOPZ และ LOOPNZ มีการทำงานเหมือนกับคำสั่ง LOOP แต่จะนำค่าของแฟล็กศูนย์มาใช้ในการพิจารณาด้วย LOOPZ จะกระโดดกลับไปทำงานถ้าค่าของ CX ที่ลดแล้วมีค่าไม่เท่ากับศูนย์ และค่าของแฟล็กศูนย์มีค่าเป็นหนึ่ง (Zero) (CX ≠ 0) and (Z = 1) LOOPNZ จะกระโดดกลับไปทำงานถ้าค่าของ CX ที่ลดแล้วมีค่าไม่เท่ากับศูนย์ และค่าของแฟล็กศูนย์มีค่าเป็นศูนย์ (Not Zero) (CX ≠ 0) and (Z = 0)
ข้อพึงระวังของการใช้คำสั่งวนรอบ กรณีที่รีจิสเตอร์ CX มีค่าเท่ากับศูนย์ก่อนการทำงานของคำสั่ง LOOP ค่าของ CX จะถูกปรับค่าเป็น 0FFFFh และการทำงานจะผิดพลาด แก้โดยใช้คำสั่ง JCXZ ในการป้องกันความผิดพลาด action_0 CXZ ENDLOOP LABEL1: action_1 action_2 action_3 LOOP LABEL1 ENDLOOP:
Question ?