610 likes | 913 Views
การกระโดดและการวนรอบ. คำสั่งกระโดด. คำสั่งกระโดดมี 3 รูปแบบ คำสั่งกระโดดแบบไม่มีเงื่อนไข คำสั่งกระโดดแบบมีเงื่อนไขตามแฟล็กซ์ คำสั่งกระโดดแบบมีเงื่อนไขตามค่าในรีจิสเตอร์. Jxx label. MOV AX, 01H ADD AX, BX CMP AX, 0 JZ TRUE JNZ FALSE TRUE : INC AX FALSE : INC CX.
E N D
คำสั่งกระโดด • คำสั่งกระโดดมี 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) • ข้อมูลที่นำมาเปรียบเทียบเป็นข้อมูลชนิดตัวเลขเสมอ แต่คำสั่งกระโดดรองรับได้ทั้งตัวเลขแบบคิดเครื่องหมายและไม่คิดเครื่องหมาย • การกระโดดทุกครั้งสามารถกระโดดไปที่เลเบลเท่านั้น ไม่สามารถกระโดดไปที่หมายเลขบรรทัดได้ การกำหนดเลเบลต้องกำหนดที่ต้นบรรทัดเท่านั้น
คำสั่งการกระโดดเบื้องต้นคำสั่งการกระโดดเบื้องต้น
คำสั่งกระโดด (ตัวเลขไม่มีเครื่องหมาย)
คำสั่งกระโดด (ตัวเลขมีเครื่องหมาย)
คำสั่งกระโดด (ตามแฟล็กซ์และรีจิสเตอร์)
Ex#1 cmp ah,10 jz lab1 mov bx,2 lab1: add cx,10 ;เปรียบเทียบ ah กับ 10 ;ถ้าเท่ากันให้กระโดดไปที่ lab1 EX#2 cmp ah,10 jge tenup add dl,’0’ jmp endif tenup: add dl,’A’ endif: ;เปรียบเทียบ ah กับ 10 ถ้ามากกว่า ;หรือเท่ากับให้กระโดดไปที่ lab1 ;ปรับค่า dl ;กระโดดไปที่ endif ;ปรับค่า dl ตัวอย่างการใช้คำสั่งกระโดด
condition False True Statement Statement Statement Statement False condition True การประยุกต์คำสั่งกระโดด Whileconditiondo statement ; Repeat Statement; Statement; Untilcondition ;
การประยุกต์คำสั่งกระโดด (repeat) Pascal Language Assembly Language ax := 10; repeat ax := ax-1; bx := bx+1; cx := ax-bx; untilax= 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 whileax < 28h do begin ax := ax+bx ; bx := bx+1 ; end; cx := cx-1 ;
คำสั่งวนรอบ • คำสั่งวนรอบเป็นคำสั่งที่ใช้ในการกระทำซ้ำ โดยใช้รีจิสเตอร์ 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:
โปรแกรมภาษาแอสเซมบลี้เบื้องต้นโปรแกรมภาษาแอสเซมบลี้เบื้องต้น
หัวข้อในวันนี้ • รูปแบบของโปรแกรมภาษาแอสเซมบลี้แบบเก่า • รูปแบบของโปรแกรมภาษาแอสเซมบลี้แบบใหม่ • การเรียกใช้บริการของ DOS • ขั้นตอนการแปลโปรแกรม • ตัวอย่างโปรแกรม
รูปแบบของโปรแกรมภาษาแอสเซมบลี้รูปแบบของโปรแกรมภาษาแอสเซมบลี้ • การโปรแกรมภาษาแอสเซมบลี้จะเขียนโปรแกรมบนเซกเมนต์ต่าง ๆ • การประกาศในเซกเมนต์ต่าง ๆ จะใช้สำหรับกำหนดข้อมูล, ขนาดของสแต็กซ์และคำสั่งในการโปรแกรม
ตัวอย่างโปรแกรมภาษาแอสเซมบลี้ตัวอย่างโปรแกรมภาษาแอสเซมบลี้ ; This program prints the message ”Hello world” dseg segment msg1 db ’Hello world’,10h,13h,’$’ dseg ends sseg segment stack db 100 dup (?) sseg ends cseg segment assume cs:cseg,ds:dseg,ss:sseg start: mov ax,dseg ;set DS mov ds,ax mov ah,9h ;print message mov dx,offset msg1 int 21h mov ax,4c00h ;exit program int 21h cseg ends end start
คำสั่งเทียม • เป็นคำสั่งที่ผู้เขียนโปรแกรมเขียนเพื่อระบุให้ assembler แปลโปรแกรมในรูปแบบที่ต้องการ • เป็นคำสั่งกลุ่มที่ไม่ปรากฏในรหัสคำสั่งภาษาเครื่อง เช่น คำสั่ง segment , db , และ assume เป็นต้น
การประกาศเซกเมนต์ • ในโปรแกรมภาษาแอสเซมบลี้เราสามารถประกาศเซกเมนต์ได้โดยใช้คำสั่งเทียม segment • การโปรแกรมทั่วไปจะประกาศเซกเมนต์ทั้งสิ้น 3 เซกเมนต์ • dseg ใช้ในการจองพื้นที่สำหรับตัวแปร • sseg ใช้ในการจองพื้นที่สำหรับสแต็กซ์ • cseg เป็นเซกเมนต์หลักที่บรรจุชุดคำสั่งที่ใช้ในการประมวลผล segment_namesegment …. segment_nameends
ตัวอย่างโปรแกรมภาษาแอสเซมบลี้ตัวอย่างโปรแกรมภาษาแอสเซมบลี้ ; This program prints the message ”Hello world” dseg segment msg1 db ’Hello world’,10h,13h,’$’ dseg ends sseg segment stack db 100 dup (?) sseg ends cseg segment assume cs:cseg,ds:dseg,ss:sseg start: mov ax,dseg ;set DS mov ds,ax mov ah,9h ;print message mov dx,offset msg1 int 21h mov ax,4c00h ;exit program int 21h cseg ends end start
การประกาศให้ assembler ทราบการใช้เซกเมนต์ • คำสั่งเทียม assume ใช้เพื่อระบุให้ assembler ทราบว่าเราจะใช้เซกเมนต์ต่าง ๆ อย่างไร • การระบุโดยวิธีนี้นั้นจะเป็นการระบุให้ assembler นำไปแปลโปรแกรมได้ถูกต้องเท่านั้น • ไม่ได้ระบุให้ assembler ตั้งค่าเซกเมนต์รีจิสเตอร์ต่างๆ ให้ ดังนั้นเราจะต้องตั้งค่าให้กับเซกเมนต์รีจิสเตอร์เอง
การประกาศให้ assembler ทราบการใช้เซกเมนต์ • เซกเมนต์ข้อมูล (DS) • จะต้องมีการกำหนดตำแหน่งเริ่มต้นให้กับ DS ก่อนการใช้งานเสมอ • เซกเมนต์คำสั่ง (CS) และแสต็กเซกเมนต์ (SS) • ระบบปฏิบัติการจะตั้งค่าของ CS และ SS ให้กับโปรแกรมเมื่อเริ่มทำงาน • ต้องระบุเซกเมนต์ที่จะใช้เป็น stack โดยใช้คำสั่งเทียม stack หลังการประกาศเซกเมนต์ที่ต้องการให้เป็นแสต็ก • เซกเมนต์คำสั่งระบบจะตั้งให้อัตโนมัติ mov ax,dseg mov ds,ax
รูปแบบโปรแกรม • การประกาศจุดเริ่มโปรแกรม • กำหนดหลังคำสั่งเทียม end ในบรรทัดสุดท้ายโดยระบุด้วย label • การประกาศเลเบล • การระบุตำแหน่งของหน่วยความจำ ทำได้โดยการสร้างเลเบลที่บรรทัดนั้น • Assembler จะจดจำแอดเดรสของเลเบลต่าง ๆ และจะนำไปแทนค่าให้ตามความเหมาะสม • การใส่หมายเหตุ • หลังเครื่องหมาย ‘ ; ’ assembler จะถือว่าเป็นหมายเหตุ label_name:
รูปแบบโปรแกรม • การสั่งให้โปรแกรมจบการทำงาน • ใช้บริการหมายเลข 4Ch ของระบบปฏิบัติการ DOS โดยใช้คำสั่ง : • การใช้บริการของระบบปฏิบัติการ DOS • สามารถใช้บริการได้หลายรูปแบบ โดยกำหนดประเภทใน AX • และเรียกใช้คำสั่ง int 21h mov ax,4C00h int 21h
ตัวอย่างโปรแกรมภาษาแอสเซมบลี้ตัวอย่างโปรแกรมภาษาแอสเซมบลี้ ; This program prints the message ”Hello world” dseg segment msg1 db ’Hello world’,10h,13h,’$’ dseg ends sseg segment stack db 100 dup (?) sseg ends cseg segment assume cs:cseg,ds:dseg,ss:sseg start: mov ax,dseg ;set DS mov ds,ax mov ah,9h ;print message mov dx,offset msg1 int 21h mov ax,4c00h ;exit program int 21h cseg ends end start
รูปแบบโปรแกรมแบบใหม่ ; This program prints "Hello world" .model small .dosseg .data msg1 db ’Hello world’,10h,13h,’$’ .stack 100h .code start: mov ax,@data mov ds,ax mov ah,9h mov dx,offset msg1 int 21h mov ax,4c00h int 21h end start
รูปแบบโปรแกรมแบบใหม่ • เพื่อให้โปรแกรมสั้นและกะทัดรัดมากขึ้น • ชื่อของ segment จะถูกประกาศให้โดยอัตโนมัติ • ชื่อของเซกเมนต์ข้อมูลคือ @data แทน dseg • การประกาศเซกเมนต์ไม่ต้องมีคำสั่ง xseg ends • จุดเริ่มต้นของการทำงานของโปรแกรมยังคงเริ่มต้นที่เลเบลภายหลังคำสั่ง end
รูปแบบโปรแกรมแบบใหม่ ; This program prints "Hello world" .model small .dosseg .data msg1 db ’Hello world’,10h,13h,’$’ .stack 100h .code start: mov ax,@data mov ds,ax mov ah,9h mov dx,offset msg1 int 21h mov ax,4c00h int 21h end start
การเรียกใช้บริการของ DOS • ระบบปฏิบัติการ DOS ได้จัดเตรียมบริการต่าง ๆ ให้ผู้เขียนโปรแกรมเรียกใช้ได้โดยผ่านทางการขัดจังหวะหมายเลข 21h • ในการเรียกใช้บริการของ DOS เราจะต้องกำหนดหมายเลขของบริการลงในรีจิสเตอร์ AH และกำหนดค่าพารามิเตอร์ต่างๆ ลงในรีจิสเตอร์ • ใช้คำสั่ง INT 21h เพื่อเรียกใช้การบริการของระบบ • รูปแบบโดยทั่วไปในการเรียกใช้บริการ คือ ; set parameters mov AH,function_number int 21h
ประเภทการบริการของ DOS • Function 01h : อ่านการกดปุ่มจากแป้นพิมพ์ AH = 01h AL = รหัสแอสกีของอักขระที่ผู้ใช้กด • Function 02h : แสดงตัวอักษรออกทางหน้าจอ AH = 02h DL = รหัสแอสกีของอักขระที่ต้องการแสดง • Function 05h : พิมพ์ตัวอักษรทางเครื่องพิมพ์ AH = 05h DL = รหัสแอสกีของอักขระที่ต้องการพิมพ์
ประเภทการบริการของ DOS • Function 07h : อ่านการกดแป้นพิมพ์ โดยไม่แสดงปุ่มที่กด (ไม่ตรวจการกด Ctrl-Break) AH = 07h AL = รหัสแอสกีของอักขระที่ผู้ใช้กด • Function 08h : อ่านการกดแป้นพิมพ์ โดยไม่แสดงปุ่มที่กด (ตรวจการกด Ctrl-Break) AH = 08h AL = รหัสแอสกีของอักขระที่ผู้ใช้กด
ประเภทการบริการของ DOS • Function 09h : แสดงข้อความทางหน้าจอ AH = 09h DS:DX = ตำแหน่งของข้อความที่ต้องการแสดง โดยข้อความนี้ต้องจบด้วยอักษร ‘$’ เท่านั้น • Function 0Ah : อ่านข้อความ AH = 0Ah DS:DX = ตำแหน่งของบัฟเฟอร์สำหรับเก็บข้อมูล • Function 4Ch : จบโปรแกรม AH = 4Ch AL = ค่าที่ต้องการคืนให้กับระบบ
ขั้นตอนการพัฒนาโปรแกรมขั้นตอนการพัฒนาโปรแกรม • สร้างโปรแกรมเก็บไว้ในแฟ้มนามสกุล ASM • ใช้โปรแกรม assembler เช่น MASM หรือ TASM แปลโปรแกรมเป็นแฟ้มเป้าหมาย (Object file) โดยใช้คำสั่ง MASM filename; • ใช้โปรแกรม LINK เพื่อเชื่อมโยงแฟ้มเป้าหมายแฟ้มเดียวหรือหลายแฟ้มเข้าด้วยกัน โดยใช้คำสั่ง LINK filename; Linker .ASM … mov A, B add B , A sub A, B push A … Assembler .ASM Hello .ASM
ตัวอย่างโปรแกรม 1 • อ่านตัวอักษรจากผู้ใช้แล้วแสดงตัวอักษรนั้นออกมา .model small .dosseg .stack 100h .code start: mov ah,01h ;read character (Func 01h) int 21h mov dl,al ;copy character to DL mov ah,02h ;display it (Func 02h) int 21h mov ax,4C00h ;Exit (Function 4Ch) int 21h end start
ตัวอย่างโปรแกรม 2 • อ่านตัวอักษรจากผู้ใช้แล้วแสดงตัวอักษรตัวถัดไปออกมา sseg segment stack db 100 dup (?) sseg ends cseg segment assume cs:cseg,ss:sseg start: mov ah,01h ;read character (Func 01h) int 21h mov dl,al ;copy to DL inc dl ;increse DL (next char.) mov ah,02h ;display it (Func 02h) int 21h mov ax,4C00h ;Exit int 21h cseg ends end start
ตัวอย่างโปรแกรม 3 • อ่านตัวอักษรพิมพ์เล็กจากผู้ใช้แล้วแสดงตัวอักษรพิมพ์ใหญ่ .model small .dosseg .stack 100h .code start: mov ah,01h ;read char. int 21h mov dl,al sub dl,32 ;change char. case mov ah,02h ;display it int 21h mov ax,4C00h ;exit int 21h end start
ตัวอย่างโปรแกรม 4 • อ่านตัวอักษรพิมพ์เล็กจากผู้ใช้แล้วแสดงตัวอักษรพิมพ์ใหญ่โดยไม่แสดงอักษรที่ผู้ใช้กดให้เห็น sseg segment stack db 100 dup (?) sseg ends cseg segment assume cs:cseg,ss:sseg start: mov ah,08h ;readchar(Func 08h) int 21h mov dl,al ;Change case sub dl,32 mov ah,02h int 21h mov ax,4C00h ;exit int 21h cseg ends end start
ตัวอย่างโจทย์ • รับการกดปุ่มจากผู้ใช้แล้วแสดงค่ารหัสแอสกีของอักขระที่ผู้ใช้กดเป็นเลขฐาน 10 (เพื่อความง่าย : ให้แสดงเป็นตัวเลข 3 หลักเสมอ) • ขั้นตอน • รับการกดปุ่ม • ใช้ Function 01h • คำนวณเลขในแต่ละหลักของรหัสแอสกี • ใช้คำสั่งทางคณิตศาสตร์ • แสดงเลขในแต่ละหลักออกมา • ใช้ Function 02h
.model small .dosseg .stack 100h .code start: mov ah,01h ;read character int 21h ;ASCII -> AL mov ah,0 mov bl,10 div bl mov cl,ah ;last digit->cl mov ah,0 div bl mov ch,ah ;2nd digit->ch mov dh,al ;1st digit->dh mov ah,02h ;disp newline mov dl,10 ;LF int 21h mov dl,13 ;CR int 21h mov ah,02h ;display ascii mov dl,dh ;1st digit add dl,'0' int 21h mov dl,ch add dl,'0' ;2nd digit int 21h mov dl,cl add dl,'0' ;3rd digit int 21h mov ax,4C00h int 21h end start
หัวข้อในวันนี้ • รูปแบบในการประกาศข้อมูล • การอ้างใช้ข้อมูลและตำแหน่งของข้อมูล • การประกาศข้อมูลสำหรับการเรียกใช้งานบริการของ DOS หมายเลข 09h และ 0Ah
ตัวอย่างโปรแกรมภาษาแอสเซมบลี้ตัวอย่างโปรแกรมภาษาแอสเซมบลี้ ; This program prints the message ”Hello world” dseg segment msg1 db ’Hello world’,10h,13h,’$’ dseg ends sseg segment stack db 100 dup (?) sseg ends cseg segment assume cs:cseg,ds:dseg,ss:sseg start: mov ax,dseg ;set DS mov ds,ax mov ah,9h ;print message mov dx,offset msg1 int 21h mov ax,4c00h ;exit program int 21h cseg ends end start
รูปแบบโปรแกรมแบบใหม่ ; This program prints "Hello world" .model small .dosseg .data msg1 db ’Hello world’,10h,13h,’$’ .stack 100h .code start: mov ax,@data mov ds,ax mov ah,9h mov dx,offset msg1 int 21h mov ax,4c00h int 21h end start
ประเภทการบริการของ DOS • Function 01h : อ่านการกดปุ่มจากแป้นพิมพ์ AH = 01h AL = รหัสแอสกีของอักขระที่ผู้ใช้กด • Function 02h : แสดงตัวอักษรออกทางหน้าจอ AH = 02h DL = รหัสแอสกีของอักขระที่ต้องการแสดง • Function 05h : พิมพ์ตัวอักษรทางเครื่องพิมพ์ AH = 05h DL = รหัสแอสกีของอักขระที่ต้องการพิมพ์
ประเภทการบริการของ DOS • Function 07h : อ่านการกดแป้นพิมพ์ โดยไม่แสดงปุ่มที่กด (ไม่ตรวจการกด Ctrl-Break) AH = 07h AL = รหัสแอสกีของอักขระที่ผู้ใช้กด • Function 08h : อ่านการกดแป้นพิมพ์ โดยไม่แสดงปุ่มที่กด (ตรวจการกด Ctrl-Break) AH = 08h AL = รหัสแอสกีของอักขระที่ผู้ใช้กด
ประเภทการบริการของ DOS • Function 09h : แสดงข้อความทางหน้าจอ AH = 09h DS:DX = ตำแหน่งของข้อความที่ต้องการแสดง โดยข้อความนี้ต้องจบด้วยอักษร ‘$’ เท่านั้น • Function 0Ah : อ่านข้อความ AH = 0Ah DS:DX = ตำแหน่งของบัฟเฟอร์สำหรับเก็บข้อมูล • Function 4Ch : จบโปรแกรม AH = 4Ch AL = ค่าที่ต้องการคืนให้กับระบบ
การประกาศข้อมูลหรือตัวแปรการประกาศข้อมูลหรือตัวแปร • ข้อมูลที่โปรแกรมใช้และตัวแปรต่างๆ ที่อยู่ในหน่วยความจำ เป็นสิ่งเดียวกัน • การประกาศข้อมูล คือ • การระบุให้ assembler จองเนื้อที่ในหน่วยความจำไว้ใช้สำหรับการเก็บข้อมูล • และตั้งชื่อให้กับหน่วยความจำตำแหน่งนั้น (สร้างเลเบล)