23 คะแนน โดย GN⁺ 2025-10-28 | 2 ความคิดเห็น | แชร์ทาง WhatsApp
  • เป็นบทช่วยสอนแบบโต้ตอบที่ช่วยให้เรียนรู้ RISC-V แอสเซมบลี แบบทีละขั้นผ่าน อีมูเลเตอร์ที่รันได้ในเว็บเบราว์เซอร์ โดยสร้างขึ้นจากแรงบันดาลใจของ Easy 6502 ของ Nick Morgan
  • ครอบคลุมคำสั่งพื้นฐาน 45 คำสั่งของ RV32I_Zicsr instruction set และแนวคิดหลักของสถาปัตยกรรมแบบมีสิทธิพิเศษ พร้อมสอนชุดคำสั่งที่สมบูรณ์เพียงพอสำหรับใช้เป็นคอมไพเลอร์ target
  • มีตัวอย่างฝึกปฏิบัติสำหรับ พื้นฐานของการเขียนโปรแกรมแอสเซมบลี เช่น การคำนวณเชิงคณิต/ตรรกะ การแตกแขนง/กระโดด การเข้าถึงหน่วยความจำ calling convention ของฟังก์ชัน และการจัดการสแตก
  • อธิบายการ สลับระดับสิทธิพิเศษ ระหว่าง Machine mode และ User mode, การจัดการ exception และวิธีจัดการ CSR (control and status registers) ด้วยโค้ดที่ใช้งานจริง
  • เป้าหมายสุดท้ายของบทช่วยสอนคือการเขียน ระบบปฏิบัติการขนาดจิ๋วที่รองรับ system call และการจัดการ exception ได้ด้วยตนเอง ทำให้เห็นภาพกระบวนการพัฒนาระดับล่างบน RISC-V แบบครบถ้วน

โครงสร้างบทช่วยสอนและหัวข้อการเรียนรู้หลัก

คำสั่งพื้นฐานและแนวคิดของโปรเซสเซอร์

  • สถานะของโปรเซสเซอร์: ทำความเข้าใจ program counter (pc), เรจิสเตอร์อเนกประสงค์ 31 ตัว (x1~x31) และ zero register พิเศษ (x0)
  • คำสั่งคณิตศาสตร์: เรียนรู้การบวก/ลบและพฤติกรรมของ overflow ผ่าน add, addi, sub เป็นต้น
  • การดำเนินการระดับบิต: ฝึกใช้คำสั่งตรรกะระดับบิตและการเลื่อนบิต เช่น and, or, xor, sll, srl, sra
  • คำสั่งเปรียบเทียบ: ใช้ slt, sltu เป็นต้น เพื่อสร้างตรรกะการเปรียบเทียบจำนวนเต็มแบบ signed/unsigned และการตัดสินใจตามเงื่อนไข

การควบคุมลำดับการทำงานและหน่วยความจำ

  • การแตกแขนงและการกระโดด: กลไกการแตกแขนงแบบมี/ไม่มีเงื่อนไขและการเรียกฟังก์ชันด้วย beq, bne, blt, jal, jalr เป็นต้น
  • การเข้าถึงหน่วยความจำ: การโหลด/เก็บข้อมูลระดับ word/halfword/byte ผ่านคำสั่ง lw, sw, lb, lh, sb, sh
  • Memory-mapped I/O: ทำความเข้าใจวิธีสื่อสารกับอุปกรณ์ภายนอกผ่านการอ่าน/เขียนไปยังแอดเดรสเฉพาะ
  • โค้ดแบบไม่ยึดติดตำแหน่ง: เทคนิคการเขียนโค้ดที่ย้ายตำแหน่งได้ด้วยคำสั่ง auipc และการอ้างแอดเดรสแบบสัมพันธ์กับ PC

ฟังก์ชันและ calling convention

  • ชื่อเรียกแทนของเรจิสเตอร์: บทบาทของ a0~a7 (อาร์กิวเมนต์), s0~s11 (ค่าที่ต้องเก็บรักษา), t0~t6 (ชั่วคราว), ra (return address), sp (stack pointer) เป็นต้น
  • การจัดการสแตก: รูปแบบการบันทึกเรจิสเตอร์เมื่อเข้าฟังก์ชัน การจอง/คืนพื้นที่สแตก และการเก็บ/กู้คืน return address
  • ฟังก์ชันเวียนเกิด: ฝึกการเรียกซ้ำและการจัดการ stack frame ผ่านการเขียนลำดับฟีโบนัชชี

สถาปัตยกรรมแบบมีสิทธิพิเศษและระบบปฏิบัติการ

  • ระดับสิทธิพิเศษ: ความแตกต่างและกลไกการแยกระหว่าง Machine mode (ระดับ 3) และ User mode (ระดับ 0)
  • คำสั่ง CSR: ใช้ csrrw, csrrs, csrrc เป็นต้น เพื่ออ่าน/เขียน control register และจัดการ bit field
  • การจัดการ exception: ตรวจสอบข้อมูล exception และเขียน handler ผ่าน CSR เช่น mcause, mepc, mtval, mstatus
  • การสลับโหมด: ใช้คำสั่ง mret เพื่อเข้าและกลับจาก User mode และใช้ mscratch สำหรับ context switching

โปรเจ็กต์สุดท้าย: OS ขนาดจิ๋ว

  • การทำ system call: ใช้คำสั่ง ecall เพื่อ trap จาก User mode ไปยัง Machine mode และให้ความสามารถ putchar/exit
  • การบันทึก/กู้คืนเรจิสเตอร์: โครงสร้างเต็มของ trap handler ที่สำรองและกู้คืนเรจิสเตอร์อเนกประสงค์ทั้งหมดลงสแตก
  • ตรรกะการจัดการ exception: ใช้ mcause แยกสาเหตุของ exception, dispatch ตามหมายเลข system call (a7) และแสดงข้อความผิดพลาด
  • โค้ดที่รันได้จริง: มีโค้ดเข้าสู่/กลับจากเคอร์เนล OS แบบสมบูรณ์ที่สามารถรันได้โดยตรงบนเว็บอีมูเลเตอร์

เอกสารอ้างอิงและไลเซนส์

  • ทั้งบทช่วยสอนและโค้ดอยู่ภายใต้ CC0 public domain หรือ 0-clause BSD license
  • ต้นฉบับและคลังโค้ด: https://github.com/dramforever/easyriscv
  • เหมาะสำหรับใช้เรียนรู้ RISC-V รวมถึง การศึกษา การวิจัย และการสร้างสภาพแวดล้อมจำลอง

2 ความคิดเห็น

 
lsdcnu 2025-11-06

ว้าว
พอเริ่มสนใจ RISC-V assembly ที่เรียนในวิชาเอกขึ้นมา.. ต่อให้คิดจะซื้อหนังสือมาอ่านแยกก็เห็นมีแต่สถาปัตยกรรม ARM ไม่มี RISC-V เลย เลยกำลังกังวลว่าควรจะอ่านอะไรดีอยู่พอดี แต่เหมือนจะเจอแหล่งข้อมูลที่ดีมากสำหรับการเรียนแล้ว
ขอบคุณครับ!!!

 
GN⁺ 2025-10-28
ความคิดเห็นจาก Hacker News
  • เป็นไกด์ที่ดีมาก
    อยากให้หน้าจออีมูเลเตอร์อันแรกของ “My first RISC-V assembly program” อยู่ต้นไกด์เลย ไม่อย่างนั้นผู้อ่านอาจเข้าใจผิดว่ามันเป็นแค่บทนำแบบข้อความล้วน ทั้งที่ชื่อบอกว่าเป็นแบบ ‘interactive’
    กะว่าจะใช้เวลากับมันต่ออีกสองสามวัน สนใจ RISC-V มากพอสมควร และคิดว่ามันมีอนาคตที่สดใส
    ถ้ามีผู้เชี่ยวชาญ AI มาเห็นโพสต์นี้ การเอา Core War กลับมาทำใหม่ด้วย RISC-V assembly บนแพลตฟอร์มอย่าง Replit หรือ Lovable น่าจะเจ๋งมาก

    • ทำไมไม่ทำด้วย สมองโดยตรง ไปเลยล่ะ?
  • ผมเรียน assembly จาก Computer Organization And Design ของ Patterson และ Hennessy แล้วรู้สึกได้ชัดเลยว่า RISC-V รับอะไรจาก MIPS มาเยอะมาก
    ISA ทั้งสองตัวมีคนกลุ่มเดียวกันมีส่วนร่วม และก็หลีกเลี่ยงความพลาดอย่าง delay slot ของ MIPS ได้ ถ้ามีประสบการณ์กับ MIPS มาก่อน RISC-V assembly จะให้ความรู้สึกว่าแทบจะเหมือนกันเลย
    ช่วงนี้ผมก็กำลังดู AArch64 อยู่เหมือนกัน ซึ่งมันดูสะอาดน้อยกว่า RISC-V แต่ก็ประทับใจกับ การออกแบบเชิงปฏิบัติ ของมัน จนบางทีก็อดคิดไม่ได้ว่า RISC-V อาจถูกออกแบบมาแบบอนุรักษ์นิยมเกินไปหรือเปล่า

    • RISC-V น่าจะใกล้กับ RISC-1 มากกว่า มีบทความที่ Patterson อธิบายไว้เอง: How close is RISC-V to RISC-I, RISC on a Chip
    • ผมก็รู้สึกถึงความคล้ายกันระหว่าง RISC-V กับ MIPS เหมือนกัน ตอนทำโฮมบรูว์ให้ Nintendo 64 มักจะคิดว่า “นี่มันแทบจะเหมือนกับที่เคยเล่นใน Ares+Godbolt มาก่อนเลย แค่ไม่มี delay slot”
    • คนส่วนใหญ่ไม่ค่อยตระหนักว่ามีหลายจุดที่ ไม่ชัดเจน ว่าการออกแบบของ AArch64 มีที่มาอย่างไร และสร้างขึ้นมาด้วยปรัชญาแบบไหน
    • การเพิ่มคำสั่งทำได้ง่าย แต่การเอาออกทำได้ยาก RISC-V เลยเริ่มจาก ชุดคำสั่งขั้นต่ำ ก่อน แล้วค่อยๆ ขยายเพิ่มทีละน้อย ถ้าจะเสนอคำสั่งใหม่ ก็ต้องพิสูจน์ให้ได้ถึง ต้นทุนและประโยชน์ที่แท้จริง ของมัน
    • จำได้ว่าใน Computer Architecture: A Quantitative Approach ก็มีพูดถึงความคล้ายกันระหว่าง RISC-V กับ MIPS อยู่เหมือนกัน แต่ตอนนี้หนังสืออยู่ในกล่องเลยไม่รู้เลขหน้าแน่ชัด
  • ผมเขียน TCP Socket in RISC-V Assembly เอง
    ใช้ RV64I ISA และต้องเข้าใจแนวคิดเรื่อง linker relaxation ด้วย ผมแนบเอกสารอ้างอิงไว้ให้แล้ว

  • เหมือนจะมีข้อผิดพลาดในส่วน Position Independence
    ในโค้ดตัวอย่าง น่าจะต้องใช้ lui แทน auipc ถึงจะได้ 0x3004 หรือเปล่า

    • ไม่ใช่ครับ lui สร้างที่อยู่แบบสัมบูรณ์ แต่คู่ auipc/addi จะสร้าง ที่อยู่แบบไม่ขึ้นกับตำแหน่ง ถ้า auipc อยู่ที่ address 0 ผลลัพธ์จะเหมือนกัน แต่ในความเป็นจริงมันคือค่าที่บวกกับ address ของคำสั่งปัจจุบัน
  • โครงสร้างแบบอินเทอร์แอ็กทีฟ ของคอนเทนต์นี้ยอดเยี่ยมมาก
    ในฐานะนักพัฒนา C/C++ ผมคิดว่า assembly เป็นเรื่องยากมาตลอด แต่วิธีนี้ช่วยให้เข้าใจได้ชัดเจนขึ้นมาก

    • โดยรวมแล้ว RISC-V assembly ค่อนข้างง่าย แต่ ตัวย่อของคำสั่ง มีเยอะเกินไปจนไม่ค่อยสะดวก แทนที่จะใช้ lw ก็อาจใช้ load4 หรือแทน j ด้วย jump ที่ตรงไปตรงมากว่านี้ก็ได้ ไม่ใช่ยุคบัตรเจาะรูแล้ว ทำไมยังต้องเขียนสั้นขนาดนี้ก็ไม่รู้
  • อ่านบทความนี้แล้วทำให้อยากกลับไปทำ การเขียนโปรแกรมระดับล่าง อีกครั้ง
    ตอนเรียนมหาวิทยาลัยสาขาเมคคาทรอนิกส์ ผมเคยทำงานกับไมโครคอนโทรลเลอร์ด้วย C และ assembly แต่ตอนนี้ย้ายมาทำสายเว็บแล้ว
    เลยสงสัยว่ามีแหล่งข้อมูล ที่เชื่อถือได้ สำหรับเรียนรู้ฮาร์ดแวร์ RISC-V ไหม ถ้าเป็นไปได้อยากลองด้วย Rust

    • ถึงจะไม่ได้ใช้ Rust ไปแตะฮาร์ดแวร์โดยตรง แต่มีบทช่วยสอนที่ดีเกี่ยวกับพื้นฐาน OS อยู่: Operating System in 1000 Lines
      แล้วก็เคยมี tutorial ทำ OS ด้วย Rust เหมือนกัน แต่ตอนนี้หาลิงก์ไม่เจอ
      ถ้าอยากได้ฮาร์ดแวร์จริง แนะนำ neorv32 — เอกสารดีมาก: เอกสารทางการ, GitHub repository เป็นคอร์ RISC-V ที่เขียนด้วย VHDL
  • ฮาร์ดแวร์ RISC-V หาได้ไม่ยาก
    ดู RISC-V on Raspberry Pi Pico 2

    • ผมก็กำลังรอ VisionFive 2 Lite ที่จะออกเร็วๆ นี้อยู่ ถึงจะขาดๆ เกินๆ เรื่องไดรเวอร์กับประสิทธิภาพไปบ้าง แต่ก็น่าจะโอเคสำหรับงานพัฒนา OS
      ดู หน้า Kickstarter
      อีกอย่าง ถ้าอยากเล่นทั้ง RISC-V และ FPGA ก็มี PolarFireSoC ด้วย ถูกกว่า AMD/Xilinx เยอะและใช้งานได้ดี สภาพแวดล้อมสำหรับพัฒนาจะ เก่าหน่อยแต่เร็ว เอกสารกระจัดกระจายไปบ้าง แต่ส่วนใหญ่ก็ยังหาเจอได้สักที่
      ลิงก์ชุดพัฒนา
      เรื่องน่าสนใจก็คือบอร์ดพัฒนากลับถูกกว่าตัวชิปเสียอีก
    • บางทีเริ่มจาก ESP-32 อาจง่ายกว่าก็ได้ เพราะหาซื้อได้ทั่วไปกว่ามาก
  • บังเอิญว่าสัปดาห์นี้ในวิชา C ของผมเพิ่งเข้าเรื่อง บทนำสู่ assembly พอดี แล้วก็คิดว่าถ้าเรียนด้วย RISC-V น่าจะเลี่ยงปัญหาเรื่องความต่างของ CPU ได้
    แต่มีคนทำสื่อที่สรุปเรื่องนี้ไว้อย่างสมบูรณ์แบบให้แล้ว ขอบคุณมากจริงๆ

  • ในตัวอย่างที่บอกว่า “ลบจาก 0 แล้วจะได้ค่าติดลบ” ค่าติดลบของ 0x123 คือ 0xfffffedd
    บอกว่าอีมูเลเตอร์แสดง 0xfffffccd แต่จริงๆ แล้ว 0xfffffedd ถึงจะถูกต้อง ผมลองคำนวณเองแล้ว และ อีมูเลเตอร์ทำงานถูกต้อง

  • ถ้ากำลังหา RISC-V emulator ดีๆ อยู่ ขอแนะนำ RARS