Monday, September 28, 2026

x86_64 Linux Yasm: Push and Pop

1. โปรแกรม Push และ Pop

 

 ภาพที่ 1 โปรแกรมแสดงการทำงาน

 

2. แสดงค่า numbers  หรือ renum ในโปรแกรม DDD

    (gdb) graph display *(long long *)(&number) 

    (gdb) graph display *(long long *)((unsigned long long) (&number + 8) 

ภาพที่ 2 การแสดงค่า numbers แล renum 

 

3. ขนาดข้อมูล ในโปรแกรมประกาศเป็น dq / resq (Quad Word) ดังนั้นใน GDB จะต้องใช้ long long

    3.1 &renum จะส่งค่า address ของ renum

    3.2 *(&renum) จะส่งค่า Value ในตัวแปร renum

    3.3 (long long *) เป็นการ cast ค่า (&renum) เพื่อบอกว่าเป็น ประเภท Pointer ( * ) มีขนาด 64-bits คือ long long

    3.4 (unsigned long long) เป็นการ cast ค่าของ &renum  และตัวถัดๆ ไป ->  โดยจะใช้โครงสร้าง(unsigned long long)&renum

รวมเป็น  *(long long *)(unsigned long long)&renum

    3.5 เมื่อต้องการดูค่าถัดไป ให้เริ่มจากค่า address ของตัวถัดไป (&renum + <byte>) เช่น &renum[1] = (&renum + 8)

 รวมเป็น *(long long *)((unsigned long long)&renum + 8)

 

4. ก่อนการ push

 

ภาพที่ 4 ตำแหน่ง rsp ก่อนการ push 

การดูค่าใน Stack : (gdb) graph display *(long long *)((unsigned long long) ($rsp)  

(gdb) x/dg $rsp 

5. ตำแหน่ง rsp หลังการ push ครั้งที่ 1$

 

ภาพที่ 5 ตำแหน่ง rsp หลังการ push ครั้งแรก 

6 ตำแหน่ง rsp หลังจาก push ครั้งที่ 2

 

 ภาพที่ 6 ตำแหน่ง push ครั้งที่สอง

 7 ตำแหน่ง rsp หลังจาก pop ครั้งที่ 1

 

 ภาพที่ 7 การ pop จะทำให้ rsp บวกขึ้นไป

Sunday, September 27, 2026

Addressing Modes X86-64 Linux YASM

 Addressing Mode X86-64 Linx YASM

 

ภาพที่ 1

 

ภาพที่ 2

 

ภาพที่ 3 

x86 LINUX Assembly YASM

 Data Declaration:

 

ภาพที่ 1 

จากภาพที่ 1 มีการประกาศตัวแปร Array: dArr32  dd   1000,  -1500, 3000

เมื่อตรวจกับ DDD ด้วยคำสั่ง x/3dw &dArr32 

ก็จะได้ค่า   0x402000:         1000    -1500    3000

 

ภาพที่ 2 ตรวจสอบค่าในแต่ละ Array 

 

โดยโครงสร้างใน Memory จะเป็นตามภาพ

1000 = 0x 00 00 03 E8

-1500 = 0x FF FF FA 24

3000 = 0x 00 00 0B B8 

 

ภาพที่ 3 ข้อมูลในแต่ละ Address 

หากต้องการดูข้อมูลในแต่ละ Address สามารถใช้คำสั่ง

gdb: x/1xb (char *)(&dArr32 + <offset>) เช่น  x/1xb (char *)(&dArr32 + 8>)

ก็จะได้ ค่า 0xB8 

!!! หมายเหตุ อย่าลืมใส่เครื่องหมาย & หน้าตัวแปร นะครับ &dArr32 

หรือ gdb: x/1xb <Address Pointer> เช่น  

x/1xb  0x402008   ก็จะได้ ค่า 0xB8 

 

ภาพที่ 4 หน้าต่าง DDD Registers
 
จะเห็นได้ว่าค่า rax ใน DDD Register จะแสดงค่า Hex ดังนี้ 0xFFFFFA24  ซึ่งตรงตามข้อมูลที่อยู่ใน Address pointer (Hex) 0x402004 - 0x402007 
แต่ค่า Dec ในคอลัมน์ที่ 3 จะแสดงค่าเป็น Unsigned คือ 4,294,965,796 สี่พันกว่าล้าน ไม่ใช่ค่า  - 1500 ที่เราอยากเห็น
ดังนั้นถ้าต้องการแสดงค่า int ให้ใช้คำสั่งเพื่อ สร้างกล่องแสดงค่า int โดยพิมพ์คำสั่งใน GDB ดังนี้ 
graph display (int)$rax

Saturday, September 26, 2026

Assembly x86 Linux : Hello, Earth!

 โปรแกรม Assembly แสดง Hello, Earth!

 

ตัวโปรแกรม 

 

msg  db "Hello. Earth!", 10 

 

* ต่อไป เป็นคำอธิบายจากการถาม เอไอ

 

len  equ $ - msg 

 

  1. mov rsi, msg ; จะได้ค่า Address Pointer ของ msg ไปเก็บใน rsi
  2. mov rsi, [msg]; จะได้ค่า ใน Byte-Addressable Memory ไปเก็บใน rsi จำนวน 8 bytes

 DDD

 

คำอธิบายเพิ่มเติม เพื่อจะได้ไม่สับสนเหมือนผม

Sunday, August 8, 2021

ARM Assembly language ตอนที่ 3

 การเปรียบเทียบค่า CMP แบบที่ 3

1.) สร้าง Flow Chart 


2.) เขียนโปรแกรมด้วย VIM
    บันทึกไฟล์ชื่อ cmp3.s



3.) สร้างไฟล์

        $ as -g -o cmp3.o  cmp3.s
        $ ld -g -o cmp3  cmp3.o


4.) Debug ด้วย ddd

       $ ddd cmp3



5.) ตรวจสอบผล



ARM Assembly language ตอนที่ 2

 การเปรียบเทียบค่า CMP แบบที่ 2

1.) สร้าง Flow Chart 




2.) เขียนโปรแกรมด้วย VIM
    บันทึกไฟล์ชื่อ cmp2.s




3.) สร้างไฟล์

        $ as -g -o cmp2.o  cmp2.s
        $ ld -g -o cmp2  cmp2.o




4.) Debug ด้วย ddd

       $ ddd cmp2




5.) ตรวจสอบผล



เริ่มเขียน ARM Assembly language มือใหม่สุดๆ ตอนที่ 1

 การเปรียบเทียบค่า CMP

1.) สร้าง Flow Chart 


2.) เขียนโปรแกรมด้วย VIM
    บันทึกไฟล์ชื่อ 01.s


3.) สร้างไฟล์

        $ as -g -o 01.o  01.s
        $ ld -g -o 01 01.o
        $ ddd 01

Debug ด้วยโปรแกรม DDD เพื่อตรวจสอบ