การประกอบ - เงื่อนไข

การดำเนินการตามเงื่อนไขในภาษาแอสเซมบลีทำได้โดยคำสั่งการวนซ้ำและการแตกแขนงหลายคำสั่ง คำแนะนำเหล่านี้สามารถเปลี่ยนขั้นตอนการควบคุมในโปรแกรม การดำเนินการตามเงื่อนไขจะสังเกตได้ในสองสถานการณ์ -

ซีเนียร์ คำแนะนำตามเงื่อนไข
1

Unconditional jump

สิ่งนี้ดำเนินการโดยคำสั่ง JMP การดำเนินการตามเงื่อนไขมักเกี่ยวข้องกับการถ่ายโอนการควบคุมไปยังที่อยู่ของคำสั่งที่ไม่เป็นไปตามคำสั่งที่กำลังดำเนินการอยู่ อาจโอนการควบคุมไปข้างหน้าเพื่อดำเนินการชุดคำสั่งใหม่หรือย้อนกลับเพื่อดำเนินการขั้นตอนเดิมซ้ำ

2

Conditional jump

ดำเนินการโดยชุดคำสั่งกระโดด j <condition> ขึ้นอยู่กับเงื่อนไข คำแนะนำแบบมีเงื่อนไขจะโอนการควบคุมโดยทำลายโฟลว์ตามลำดับและดำเนินการโดยเปลี่ยนค่าออฟเซ็ตใน IP

ให้เราหารือเกี่ยวกับคำสั่ง CMP ก่อนที่จะพูดถึงคำแนะนำแบบมีเงื่อนไข

คำสั่ง CMP

คำสั่ง CMP เปรียบเทียบสองตัวถูกดำเนินการ โดยทั่วไปจะใช้ในการดำเนินการตามเงื่อนไข คำสั่งนี้โดยทั่วไปจะลบตัวถูกดำเนินการหนึ่งตัวออกจากอีกตัวหนึ่งเพื่อเปรียบเทียบว่าตัวถูกดำเนินการเท่ากันหรือไม่ ไม่รบกวนตัวดำเนินการปลายทางหรือต้นทาง ใช้ร่วมกับคำแนะนำการกระโดดแบบมีเงื่อนไขเพื่อการตัดสินใจ

ไวยากรณ์

CMP destination, source

CMP เปรียบเทียบฟิลด์ข้อมูลตัวเลขสองฟิลด์ ตัวถูกดำเนินการปลายทางอาจอยู่ในรีจิสเตอร์หรือในหน่วยความจำ ตัวถูกดำเนินการต้นทางอาจเป็นข้อมูลคงที่ (ทันที) รีจิสเตอร์หรือหน่วยความจำ

ตัวอย่าง

CMP DX,	00  ; Compare the DX value with zero
JE  L7      ; If yes, then jump to label L7
.
.
L7: ...

CMP มักใช้เพื่อเปรียบเทียบว่าค่าตัวนับถึงจำนวนครั้งที่ต้องรันลูปหรือไม่ พิจารณาเงื่อนไขทั่วไปดังต่อไปนี้ -

INC	EDX
CMP	EDX, 10	; Compares whether the counter has reached 10
JLE	LP1     ; If it is less than or equal to 10, then jump to LP1

กระโดดอย่างไม่มีเงื่อนไข

ดังที่ได้กล่าวไว้ก่อนหน้านี้ดำเนินการโดยคำสั่ง JMP การดำเนินการตามเงื่อนไขมักเกี่ยวข้องกับการถ่ายโอนการควบคุมไปยังที่อยู่ของคำสั่งที่ไม่เป็นไปตามคำสั่งที่กำลังดำเนินการอยู่ อาจโอนการควบคุมไปข้างหน้าเพื่อดำเนินการชุดคำสั่งใหม่หรือย้อนกลับเพื่อดำเนินการขั้นตอนเดิมซ้ำ

ไวยากรณ์

คำสั่ง JMP ระบุชื่อเลเบลซึ่งโฟลว์ของการควบคุมจะถูกโอนทันที ไวยากรณ์ของคำสั่ง JMP คือ -

JMP	label

ตัวอย่าง

ข้อมูลโค้ดต่อไปนี้แสดงคำสั่ง JMP -

MOV  AX, 00    ; Initializing AX to 0
MOV  BX, 00    ; Initializing BX to 0
MOV  CX, 01    ; Initializing CX to 1
L20:
ADD  AX, 01    ; Increment AX
ADD  BX, AX    ; Add AX to BX
SHL  CX, 1     ; shift left CX, this in turn doubles the CX value
JMP  L20       ; repeats the statements

กระโดดตามเงื่อนไข

หากเงื่อนไขที่ระบุเป็นที่พอใจในการกระโดดแบบมีเงื่อนไขโฟลว์ควบคุมจะถูกโอนไปยังคำสั่งเป้าหมาย มีคำแนะนำในการกระโดดตามเงื่อนไขมากมายขึ้นอยู่กับเงื่อนไขและข้อมูล

ต่อไปนี้เป็นคำแนะนำการข้ามแบบมีเงื่อนไขที่ใช้กับข้อมูลที่ลงนามที่ใช้สำหรับการคำนวณทางคณิตศาสตร์ -

คำแนะนำ คำอธิบาย ทดสอบธงแล้ว
JE / JZ Jump Equal หรือ Jump Zero ZF
JNE / JNZ กระโดดไม่เท่ากันหรือกระโดดไม่เป็นศูนย์ ZF
JG / JNLE กระโดดมากขึ้นหรือกระโดดไม่น้อย / เท่ากัน ของ, SF, ZF
JGE / JNL กระโดดมากกว่า / เท่ากันหรือกระโดดไม่น้อย ของ, SF
JL / JNGE กระโดดน้อยลงหรือกระโดดไม่มากกว่า / เท่ากัน ของ, SF
JLE / JNG กระโดดน้อยลง / เท่ากันหรือกระโดดไม่มาก ของ, SF, ZF

ต่อไปนี้เป็นคำแนะนำการกระโดดตามเงื่อนไขที่ใช้กับข้อมูลที่ไม่ได้ลงชื่อซึ่งใช้สำหรับการดำเนินการทางตรรกะ -

คำแนะนำ คำอธิบาย ทดสอบธงแล้ว
JE / JZ Jump Equal หรือ Jump Zero ZF
JNE / JNZ กระโดดไม่เท่ากันหรือกระโดดไม่เป็นศูนย์ ZF
JA / JNBE กระโดดขึ้นไปข้างบนหรือกระโดดไม่ต่ำกว่า / เท่ากับ CF, ZF
JAE / JNB กระโดดสูงกว่า / เท่ากันหรือกระโดดไม่ต่ำกว่า CF
เจบี / เจเอ็นเอ กระโดดด้านล่างหรือกระโดดไม่สูงกว่า / เท่ากัน CF
JBE / JNA กระโดดด้านล่าง / เท่ากันหรือกระโดดไม่เหนือ AF, CF

คำแนะนำการกระโดดตามเงื่อนไขต่อไปนี้มีการใช้งานพิเศษและตรวจสอบค่าของแฟล็ก -

คำแนะนำ คำอธิบาย ทดสอบธงแล้ว
JXCZ กระโดดถ้า CX เป็นศูนย์ ไม่มี
JC กระโดดหากพกพา CF
JNC กระโดดถ้าไม่มีการพกพา CF
กระโดดถ้าล้น ของ
JNO กระโดดถ้าไม่มีล้น ของ
JP / JPE Jump Parity หรือ Jump Parity Even PF
JNP / JPO Jump No Parity หรือ Jump Parity Odd PF
JS Jump Sign (ค่าลบ) SF
จส Jump No Sign (ค่าบวก) SF

ไวยากรณ์สำหรับชุดคำสั่ง J <condition> -

ตัวอย่าง,

CMP	AL, BL
JE	EQUAL
CMP	AL, BH
JE	EQUAL
CMP	AL, CL
JE	EQUAL
NON_EQUAL: ...
EQUAL: ...

ตัวอย่าง

โปรแกรมต่อไปนี้แสดงตัวแปรสามตัวที่ใหญ่ที่สุด ตัวแปรคือตัวแปรสองหลัก ตัวแปรทั้งสาม num1, num2 และ num3 มีค่า 47, 22 และ 31 ตามลำดับ -

section	.text
   global _start         ;must be declared for using gcc

_start:	                 ;tell linker entry point
   mov   ecx, [num1]
   cmp   ecx, [num2]
   jg    check_third_num
   mov   ecx, [num2]
   
	check_third_num:

   cmp   ecx, [num3]
   jg    _exit
   mov   ecx, [num3]
   
	_exit:
   
   mov   [largest], ecx
   mov   ecx,msg
   mov   edx, len
   mov   ebx,1	;file descriptor (stdout)
   mov   eax,4	;system call number (sys_write)
   int   0x80	;call kernel
	
   mov   ecx,largest
   mov   edx, 2
   mov   ebx,1	;file descriptor (stdout)
   mov   eax,4	;system call number (sys_write)
   int   0x80	;call kernel
    
   mov   eax, 1
   int   80h

section	.data
   
   msg db "The largest digit is: ", 0xA,0xD 
   len equ $- msg 
   num1 dd '47'
   num2 dd '22'
   num3 dd '31'

segment .bss
   largest resb 2

เมื่อโค้ดด้านบนถูกคอมไพล์และเรียกใช้งานโค้ดจะได้ผลลัพธ์ดังนี้ -

The largest digit is: 
47