Skip to content

Instantly share code, notes, and snippets.

@birowo
Last active September 27, 2018 03:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save birowo/4e6ed6ca1fc06ef67a4bccbff31d1c69 to your computer and use it in GitHub Desktop.
Save birowo/4e6ed6ca1fc06ef67a4bccbff31d1c69 to your computer and use it in GitHub Desktop.
GOLANG: latihan kode assembly
buat file lat_asm.go :
package main
func a(b []byte) {
for c, d := range b {
/*
if d<'A' || d>'Z' {
continue
}
*/
b[c] = d + 'a' - 'A'
}
}
func main() {
b := []byte("QWERTYUIOP")
a(b)
println(string(b))
}
dari terminal / command-line jalankan :
>go tool compile -S -l lat_asm.go
hasil berupa kode assembly seperti di gambar: cmd
kemudian buat file lat_asm.s :
TEXT main·a(SB), $0-24 //func a
MOVQ 16(SP), AX //register AX menyimpan len dari data type []byte yg di pass ke var b
MOVQ 8(SP), CX //register CX menyimpan offset address dari data type []byte yg di pass ke var b
XORL DX, DX //set register DX ke 0 yg kemudian dipakai u/ menyimpan nilai increment
JMP L0 //jump ke instruksi di label 0 (CMPQ DX, AX)
L1 MOVBLZX (CX)(DX*1), BX //simpan setiap byte dari data []byte ke register BX
ADDL $32, BX //kurangi nilai di register BX dengan 32. 32 didapat dari 'a'-'A'
MOVB BL, (CX)(DX*1) //simpan nilai register BL(byte ke-0 dari BX) ke setiap byte dari data []byte
INCQ DX //tambah nilai register DX dengan 1
L0: CMPQ DX, AX //bandingkan DX dengan AX , jika nilai DX < nilai AX ,maka SF(sign flag) != OF(overflow flag)
JLT L1 //jika SF != OF maka jump ke label 1 : https://hjlebbink.github.io/x86doc/html/Jcc.html (JL rel8)
RET //new-line(Enter di akhir file)
kemudian ubah file lat_asm.go :
package main
//go:noinline
func a(b []byte)
func main() {
b := []byte("QWERTYUIOP")
a(b)
println(string(b))
}
yaitu dengan menghapus bagian implementasi dari dari func a,
kemudian dari IDE / terminal jalankan build:
>go build lat_asm.go
>lat_asm
qwertyuiop
jadi kesimpulannya: di file.go bisa dibuat fungsi tanpa bagian implementasinya,
dan bagian implementasinya dibuatkan di file.s dengan bahasa assembly
kode assembly hasil go tool compile -S -l ... ini kemudian bisa kita pelajari & mencari kemungkinan optimasi,
misal kode assembly di atas bisa dibuat jadi seperti ini:
TEXT main·a(SB), $0-24
MOVQ 16(SP), AX
MOVQ 8(SP), CX
L1: DECQ AX
JS L0
MOVB (CX)(AX*1), BL
ADDL $32, BX
MOVB BL, (CX)(AX*1)
JMP L1
L0: RET
apakah ada kemungkinan kode optimasi lainnya ??? jawabannya: ADA. silahkan pelajari instruction set dari x86-64:
http://linasm.sourceforge.net/docs/instructions/index.php , ada perbedaan cara penulisannya di golang:
https://quasilyte.github.io/blog/post/go-asm-complementary-reference ,
https://blog.hackercat.ninja/post/quick_intro_to_go_assembly ,
https://science.raphael.poss.name/go-calling-convention-x86-64.html
untuk memulai belajar memahami hasil dari go tool compile -S -l file.go :
https://github.com/teh-cmc/go-internals/blob/master/chapter1_assembly_primer/README.md . jangan lupa telusuri &
pelajari juga link-link yang tercantum di referensi - referensi ini.
package main
//go:noinline
func a(b []byte)
func main() {
b := []byte("QWERTYUIOP")
a(b)
println(string(b))
}
TEXT main·a(SB), $0-24
MOVQ 16(SP), AX
MOVQ 8(SP), CX
L1: DECQ AX
JS L0
MOVB (CX)(AX*1), BL
ADDL $32, BX
MOVB BL, (CX)(AX*1)
JMP L1
L0: RET
//new-line(Enter) di-akhir file

kode dari hasil go tool compile -S -l lat_asm.go bagian TEXT "".a(SB), NOSPLIT, $0-24 ... RET setelah dioptimasi: lat_asm1

hasil berupa kode assembly dari cmd: >go tool compile -S -l lat_asm.go lat_asm2

skrip awal :

lat_asm5

dilihat versi kode assembly -nya :

lat_asm4

dibuatkan kode optimasi-nya :

lat_asm3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment