Thursday, November 17, 2005

มาลองทำ Assembler กัน (พื้นฐาน)

จริง ๆ แล้ว ภาษา assembly มันก็ภาษาเครื่องแหละ แต่มันเขียนสะดวกกว่านิดนึง ... อะไรที่เราควรจะกำหนดเพิ่มไว้ก่อนหละ? ก็เรื่อง label กับ ตัวแปรไง

Local Variables (อีกแล้ว)

สมมติว่า เราจะเขียนว่า

  void f()
  {
    int x;
    int y;
    x = 0;
    y = x + 500;
  }

เดิมเราจะเขียนว่า

  f:
    VAR 2
    PBASE
    PUSH 1
    SUB
    PUSH 0
    STORE
    PBASE
    PUSH 2
    SUB
    PBASE
    PUSH 1
    SUB
    LOAD
    PUSH 500
    ADD
    STORE
    ...
    FVAR
    PUSH ค่ามั่ว ๆ อะไรก็ได้
    RETURN

จะเห็นว่า การอ้างถึงตัว y จะต้องใช้ 3 คำสั่ง คือ

    PBASE
    PUSH 2
    SUB

เพื่อลดเรื่องยุ่งพวกนี้ เราก็กำหนดภาษาใหม่ แบบนี้

  f:
    VAR 2
    REF x 1 (บอกให้ x = BP - 1)
  REF y 2 (บอกให้ y = BP - 2)
    PVAR x
    PUSH 0
    STORE
    PVAR y
    PVAR x
    LOAD
    PUSH 500
    ADD
    STORE
    ...
    FVAR
    PUSH ค่ามั่ว ๆ อะไรก็ได้
    RETURN

Labels

เราใช้ Label ไปหลายทีแล้วโดยที่ไม่ได้พูดถึง ... จริง ๆ แล้ว การจะกระโดดไปที่ label ต่าง ๆ จำเป็นจะต้องรู้ address ของ label เหล่านั้น ...

ดังนั้น Assembler ของเรา จะต้องมีความสามารถในการ แปลง label เหล่านั้น ให้เป็น address จริง ๆ

สมมติว่ามี code แบบนี้

  int f()
  {
    int x;
    int y;
    do {
    x = ReadFromSomewhere();
      y = ReadFromSomewhere();
    } while (x != y);
    return 0;
  }

จะเขียนเป็น Assembly ได้แบบนี้

  f:
    VAR 2
    REF x 1
    REF y 2
  loop:
    PVAR x
    PUSH ReadFromSomewhere
    CALL
    PVAR y
    PUSH ReadFromSomewhere
    CALL
    PVAR x
    LOAD
    PVAR y
    LOAD
    SUB
    PUSH loop
    JNZ
    FVAR
    PUSH 0
    RETURN

ซึ่ง ตอนที่แปลเป็นภาษาเครื่อง เราจะต้องรู้ 3 อย่างคือ
  • ตำแหน่งเริ่มต้นของ f → สมมติว่าเป็น 1234h
  • ตำแหน่งเริ่มต้นของ ReadFromSomewhere → สมมติว่าเป็น 5678h
  • ขนาดของ instruction → สมมติว่าเป็น 2
จากตำแหน่งเริ่มต้นของ f และขนาดของ instruction เราจะสามารถหาตำแหน่งของ loop ได้ ทำให้สามารถแปล assembly ข้างบนเป็นภาษาเครื่องได้ ดังนี้

  1234h: PUSH
  1236h: PUSH
  1238h: PBASE
  123Ah: PUSH 1
  123Ch: SUB
  123Eh: PUSH 5678h
  1240h: CALL
  1242h: PBASE
  1244h: PUSH 2
  1246h: SUB
  1248h: PUSH 5678h
  124Ah: CALL
  124Ch: PBASE
  124Eh: PUSH 1
  1250h: SUB
  1252h: LOAD
  1254h: PBASE
  1256h: PUSH 2
  1258h: SUB
  125Ah: LOAD
  125Ch: SUB
  125Eh: PUSH 1238h
  1260h: JNZ
  1262h: PUSH 0
  1264h: RETURN

คราวหน้า มาดูเรื่อง Literal กันนะ

0 Comments:

Post a Comment

<< Home