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