CS344-321 Assembly Language Programming

Download Report

Transcript CS344-321 Assembly Language Programming

CS344-321 Assembly
Language Programming
Period 32
PARAMETER PASSING
่ การเรียกใช้โปรแกรม
ในภาษาระด ับสู ง เมือมี
ย่อย พารามิเตอร ์อาจจะส่งผ่านทาง เรจิสเตอร ์ หรือ
กองซ ้อน หรือผสมกัน
การผ่านทางเรจิสเตอร ์จะเร็วกว่า แต่มข
ี อ
้ จากัด
เนื่องจากจานวน เรจิสเตอร ์มีน้อย ถ้ามีพารามิเตอร ์
จานวนมากไม่สามารถผ่านทางเรจิสเตอร ์ได้หมด
ต่อไปจะกล่าวถึงเฉพาะการผ่านพารามิเตอร ์ทาง
กองซ ้อน เนื่องจากการผ่านพารามิเตอร ์ทางเรจิ
สเตอร ์ตรงไปตรงมา ไม่ตอ
้ งกล่าวถึงอีก (ดูต ัวอย่างการ
เรียกใช้บริการของ BIOS หรือ DOS หรือ atoi หรือ
itoa)
่ การ
ตามข้อตกลงของภาษาระด ับสู ง เมือมี
เรียกใช้โปรแกรมย่อย จะเกิดกรอบกองซ ้อน
stack
bp + 6
bp + 4
bp + 2
bp
bp - 2
bp - 4
ผูถ้ ก
ู เรียก
parameter 1
parameter 2
…
จัดการโดยผูเ้ รียก
parameter n -1
parameter n
return address
dynamic link
local variable 1
local variable 2
จัดการโดย
…
กรณี near
local variable n
stack
bp + 8
bp + 6
bp + 2
bp
bp - 2
bp - 4
ผูถ้ ก
ู เรียก
parameter 1
parameter 2
…
จัดการโดยผูเ้ รียก
parameter n -1
parameter n
return address
dynamic link
local variable 1
local variable 2
จัดการโดย
…
กรณี far call
local variable n
ผู เ้ รียกจะดาเนิ นการต่อไปนี ้
่
ถ้ามีพารามิเตอร ์
กดค่าหรือเลขทีของ
้
่ก ับว่าเป็ นการส่งพารามิเตอร ์แบบ
พารามิเตอร ์ (ขึนอยู
ไหน) ลงบนกองซ ้อนในช่วงกระทาการตามลาดับ จาก
ตัวแรกถึงตัวสุดท้าย ถ้าเป็ นภาษาปาสคาล ตัวสุดท้าย
จะอยู ่บนสุด แต่ถา้ เป็ นภาษาซี จะทากลับกัน
่ อยหรือฟั งก ์ช ันทีต้
่ องการ
เรียกใช้ชด
ุ คาสังย่
่ า
ภาษาแอสเซมบลี 8086/8088 มีคาสัง่ call ซึงท
่ โดยตรง
้
่ บ (return
หน้าทีนี
คาสัง่ call จะกดเลขทีกลั
่
่
address : เลขทีของค
าสังถัดจากค
าสัง่ call) ลงบน
กองซ ้อนในช่วงกระทาการ
แล้วกระโดดไปทางานที่
่ อยหรือฟั งก ์ช ันทีต้
่ องการ (สถาปั ตยกรรม
ชุดคาสังย่
้ องกด
บางแบบไม่มค
ี าสัง่ call โดยตรง ในกรณี นีต้
ตัวอย่าง ภาษา Pascal
procedure
subr(para1:integer,
var
para2:integer, …, paran:integer)
เรียกใช้ดว้ ย
subr(para1, para2, …, paran);
ภาษาเอสเซมบลี
mov ax,para1
; call by value
push
ax
lea ax,para2
; call by reference
push
ax
…
mov ax,paran
push
ax
; call by value
่ วธ
ตัวอย่าง ภาษา C ซึงมี
ิ ก
ี ารผ่านค่าโดย value
้
เท่านัน
subr(int para1, int para2, …, int paran)
เรียกใช้ดว้ ย
subr(para1, para2, …, paran);
ภาษาเอสเซมบลี
mov ax,paran
push
ax
...
mov ax,para2
push
ax
mov ax,para1
push
ax
call subr
ผู ถ
้ ูกเรียก จะมีการดาเนิ นการ ดังต่อไปนี ้
- กดค่าโยงพลว ัต (dynamic link) ลงบนกอง
ซ ้อนในช่วงกระทาการ
้ ให้
่ ก ับต ัวแปรท้องถินบนกองซ
่
จองเนื อที
้อน
ในช่วงกระทาการ
่
เขียนเป็ นคาสังภาษาแอสเซมบลี
8086/8088
ด ังนี ้
subr proc near
push
bp ; dynamic link
mov bp,sp
sub sp,_total_local_sizes
ได้
่ ถ
เมือผู
้ ูกเรียกทางานเสร็จ จะต้องลบกรอบกอง
ซ ้อนทิง้
วิธก
ี ารลบทาได้ง่าย ๆ โดยการใช้คาสัง่
ต่อไปนี ้
mov sp,bp
pop bp
ret total_parm_sizes
subr endp
่ total_parm_sizes เป็ นเลขจานวนเต็ม มีคา
เมือ
่
้
เท่ากับขนาดของพารามิเตอร ์รวมกันทังหมด
ตวั อย่าง จากโปรแกรมภาษาปาสกาล ข่อไปนี ้
program final(input,output);
var i,j:integer;
procedure swap(var x,y:integer);
var t : integer;
begin
t:=x;
x:=y;
y:=t;
end;
begin
swap(i,j);
end.
จงเขียนโปรแกรมภาษาแอสเซมบลี 8086/8088 ให้ทางานเหมือน
โปรแกรมภาษา Pascal ข้างต้น โดยให้มก
ี ารผ่านพารามิเตอร ์ทางกอง
ซ ้อน ตามข้อตกลงของภาษา Pascal
dosseg
.model small
.stack 128
.data
; define global variables here
i
dw
?
j
dw
?
.code
swap
x
y
t
proc near
equ [bp+6]
; parameter x
equ [bp+4]
; parameter y
equ [bp-2] ; local variable t
push bp
; save old bp as dynamic link
mov bp,sp ; set bp point to stack frame
sub sp,2 ; allocate space for t
push bx
; save content of bx
mov bx,x ; t := x be careful x keeps address of i
not value of i
mov ax,[bx] ; keep value of x in ax
mov t,ax ; then copy to t
mov bx,y ; x:=y be careful x and y keep address
of i and j
mov ax,[bx] ; keep value of y in ax
mov bx,x
mov [bx],ax ; then copy to x
pop
mov
pop
ret
swap endp
main proc
mov
mov
lea
push
lea
push
call
mov
int
main endp
end
bx
; restore content of bx
sp,bp
bp
4
near
ax,@data
ds,ax
ax,i
; pass parameters (Pascal Convention)
ax
ax,j
ax
swap ; call swap
ax,4c00h
21h
main
กรณี nested call หรือ recursive call เช่น
main call A แล้ว A call B
main{ … ; call A; … }
proc A { …; call B; … }
proc B { … }
จะเกิด stack frame บน stack ดังนี ้
หมายเหตุ แสดงเฉพาะ dynamic link และ
stack frame pointer
bp ของ main เป็ นอะไร ก็ได ้
bp
ของ A
stack frame
bp
ของ B
stack frame