Added assembler instructions

This commit is contained in:
Eduard Urbach 2023-10-21 13:41:47 +02:00
parent 61af142930
commit 4967719902
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
10 changed files with 438 additions and 21 deletions

8
src/asm/Assembler.go Normal file
View File

@ -0,0 +1,8 @@
package asm
import "bytes"
type Assembler struct {
Code bytes.Buffer
Data bytes.Buffer
}

View File

@ -0,0 +1,11 @@
package x64
import "io"
// AppendUint32 appends a 32 bit number in Little Endian to the given writer.
func AppendUint32(w io.ByteWriter, number uint32) {
w.WriteByte(byte(number))
w.WriteByte(byte(number >> 8))
w.WriteByte(byte(number >> 16))
w.WriteByte(byte(number >> 24))
}

View File

@ -0,0 +1,10 @@
package x64
import (
"io"
)
func MoveRegNum32(w io.ByteWriter, register byte, number uint32) {
w.WriteByte(0xb8 + register)
AppendUint32(w, number)
}

10
src/asm/x64/Syscall.go Normal file
View File

@ -0,0 +1,10 @@
package x64
import (
"io"
)
func Syscall(w io.ByteWriter) {
w.WriteByte(0x0f)
w.WriteByte(0x05)
}

View File

@ -2,23 +2,24 @@ package build
import ( import (
"bufio" "bufio"
"bytes"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
"git.akyoto.dev/cli/q/src/asm"
"git.akyoto.dev/cli/q/src/asm/x64"
"git.akyoto.dev/cli/q/src/directory" "git.akyoto.dev/cli/q/src/directory"
"git.akyoto.dev/cli/q/src/elf" "git.akyoto.dev/cli/q/src/elf"
"git.akyoto.dev/cli/q/src/errors" "git.akyoto.dev/cli/q/src/errors"
"git.akyoto.dev/cli/q/src/log" "git.akyoto.dev/cli/q/src/log"
"git.akyoto.dev/cli/q/src/register"
"git.akyoto.dev/cli/q/src/syscall"
) )
// Build describes a compiler build. // Build describes a compiler build.
type Build struct { type Build struct {
Name string Name string
Directory string Directory string
Code bytes.Buffer
Data bytes.Buffer
WriteExecutable bool WriteExecutable bool
} }
@ -39,11 +40,26 @@ func (build *Build) Run() error {
return err return err
} }
if build.WriteExecutable { if !build.WriteExecutable {
return writeToDisk(build.Executable(), build.Code.Bytes(), build.Data.Bytes()) return nil
} }
return nil final := asm.Assembler{}
code := &final.Code
data := &final.Data
x64.MoveRegNum32(code, register.Syscall0, syscall.Write)
x64.MoveRegNum32(code, register.Syscall1, 1)
x64.MoveRegNum32(code, register.Syscall2, 0x4000a2)
x64.MoveRegNum32(code, register.Syscall3, 6)
x64.Syscall(code)
x64.MoveRegNum32(code, register.Syscall0, syscall.Exit)
x64.MoveRegNum32(code, register.Syscall1, 0)
x64.Syscall(code)
data.WriteString("Hello\n")
return writeToDisk(build.Executable(), code.Bytes(), data.Bytes())
} }
// Compile compiles all the functions. // Compile compiles all the functions.
@ -66,19 +82,6 @@ func (build *Build) Compile() error {
log.Info.Println(file) log.Info.Println(file)
}) })
build.Code.Write([]byte{
0xb8, 0x01, 0x00, 0x00, 0x00, // mov eax, 1
0xbf, 0x01, 0x00, 0x00, 0x00, // mov edi, 1
0xbe, 0xa2, 0x00, 0x40, 0x00, // mov esi, 0x4000a2
0xba, 0x06, 0x00, 0x00, 0x00, // mov edx, 6
0x0f, 0x05, // syscall
0xb8, 0x3c, 0x00, 0x00, 0x00, // mov eax, 60
0xbf, 0x00, 0x00, 0x00, 0x00, // mov edi, 0
0x0f, 0x05, // syscall
})
build.Data.Write([]byte{'H', 'e', 'l', 'l', 'o', '\n'})
return nil return nil
} }

View File

@ -5,8 +5,7 @@ const (
TypeExecutable = 2 TypeExecutable = 2
ArchitectureAMD64 = 0x3E ArchitectureAMD64 = 0x3E
HeaderSize = 64 HeaderSize = 64
CacheLineSize = 64 Align = 16
Align = CacheLineSize
) )
// Header contains general information. // Header contains general information.

20
src/register/General.go Normal file
View File

@ -0,0 +1,20 @@
package register
const (
R0 = iota
R1
R2
R3
R4
R5
R6
R7
R8
R9
R10
R11
R12
R13
R14
R15
)

12
src/register/Named.go Normal file
View File

@ -0,0 +1,12 @@
package register
const (
RAX = R0
RCX = R1
RDX = R2
RBX = R3
RSP = R4
RBP = R5
RSI = R6
RDI = R7
)

View File

@ -0,0 +1,11 @@
package register
const (
Syscall0 = R0
Syscall1 = R7
Syscall2 = R6
Syscall3 = R2
Syscall4 = R10
Syscall5 = R8
Syscall6 = R9
)

View File

@ -0,0 +1,333 @@
package syscall
const (
Read = iota
Write
Open
Close
Stat
Fstat
Lstat
Poll
Lseek
Mmap
Mprotect
Munmap
Brk
Rt_sigaction
Rt_sigprocmask
Rt_sigreturn
Ioctl
Pread64
Pwrite64
Readv
Writev
Access
Pipe
Select
Sched_yield
Mremap
Msync
Mincore
Madvise
Shmget
Shmat
Shmctl
Dup
Dup2
Pause
Nanosleep
Getitimer
Alarm
Setitimer
Getpid
Sendfile
Socket
Connect
Accept
Sendto
Recvfrom
Sendmsg
Recvmsg
Shutdown
Bind
Listen
Getsockname
Getpeername
Socketpair
Setsockopt
Getsockopt
Clone
Fork
Vfork
Execve
Exit
Wait4
Kill
Uname
Semget
Semop
Semctl
Shmdt
Msgget
Msgsnd
Msgrcv
Msgctl
Fcntl
Flock
Fsync
Fdatasync
Truncate
Ftruncate
Getdents
Getcwd
Chdir
Fchdir
Rename
Mkdir
Rmdir
Creat
Link
Unlink
Symlink
Readlink
Chmod
Fchmod
Chown
Fchown
Lchown
Umask
Gettimeofday
Getrlimit
Getrusage
Sysinfo
Times
Ptrace
Getuid
Syslog
Getgid
Setuid
Setgid
Geteuid
Getegid
Setpgid
Getppid
Getpgrp
Setsid
Setreuid
Setregid
Getgroups
Setgroups
Setresuid
Getresuid
Setresgid
Getresgid
Getpgid
Setfsuid
Setfsgid
Getsid
Capget
Capset
Rt_sigpending
Rt_sigtimedwait
Rt_sigqueueinfo
Rt_sigsuspend
Sigaltstack
Utime
Mknod
Uselib
Personality
Ustat
Statfs
Fstatfs
Sysfs
Getpriority
Setpriority
Sched_setparam
Sched_getparam
Sched_setscheduler
Sched_getscheduler
Sched_get_priority_max
Sched_get_priority_min
Sched_rr_get_interval
Mlock
Munlock
Mlockall
Munlockall
Vhangup
Modify_ldt
Pivot_root
Sysctl
Prctl
Arch_prctl
Adjtimex
Setrlimit
Chroot
Sync
Acct
Settimeofday
Mount
Umount2
Swapon
Swapoff
Reboot
Sethostname
Setdomainname
Iopl
Ioperm
Create_module
Init_module
Delete_module
Get_kernel_syms
Query_module
Quotactl
Nfsservctl
Getpmsg
Putpmsg
Afs_syscall
Tuxcall
Security
Gettid
Readahead
Setxattr
Lsetxattr
Fsetxattr
Getxattr
Lgetxattr
Fgetxattr
Listxattr
Llistxattr
Flistxattr
Removexattr
Lremovexattr
Fremovexattr
Tkill
Time
Futex
Sched_setaffinity
Sched_getaffinity
Set_thread_area
Io_setup
Io_destroy
Io_getevents
Io_submit
Io_cancel
Get_thread_area
Lookup_dcookie
Epoll_create
Epoll_ctl_old
Epoll_wait_old
Remap_file_pages
Getdents64
Set_tid_address
Restart_syscall
Semtimedop
Fadvise64
Timer_create
Timer_settime
Timer_gettime
Timer_getoverrun
Timer_delete
Clock_settime
Clock_gettime
Clock_getres
Clock_nanosleep
Exit_group
Epoll_wait
Epoll_ctl
Tgkill
Utimes
Vserver
Mbind
Set_mempolicy
Get_mempolicy
Mq_open
Mq_unlink
Mq_timedsend
Mq_timedreceive
Mq_notify
Mq_getsetattr
Kexec_load
Waitid
Add_key
Request_key
Keyctl
Ioprio_set
Ioprio_get
Inotify_init
Inotify_add_watch
Inotify_rm_watch
Migrate_pages
Openat
Mkdirat
Mknodat
Fchownat
Futimesat
Newfstatat
Unlinkat
Renameat
Linkat
Symlinkat
Readlinkat
Fchmodat
Faccessat
Pselect6
Ppoll
Unshare
Set_robust_list
Get_robust_list
Splice
Tee
Sync_file_range
Vmsplice
Move_pages
Utimensat
Epoll_pwait
Signalfd
Timerfd_create
Eventfd
Fallocate
Timerfd_settime
Timerfd_gettime
Accept4
Signalfd4
Eventfd2
Epoll_create1
Dup3
Pipe2
Inotify_init1
Preadv
Pwritev
Rt_tgsigqueueinfo
Perf_event_open
Recvmmsg
Fanotify_init
Fanotify_mark
Prlimit64
Name_to_handle_at
Open_by_handle_at
Clock_adjtime
Syncfs
Sendmmsg
Setns
Getcpu
Process_vm_readv
Process_vm_writev
Kcmp
Finit_module
Sched_setattr
Sched_getattr
Renameat2
Seccomp
Getrandom
Memfd_create
Kexec_file_load
Bpf
Stub_execveat
Userfaultfd
Membarrier
Mlock2
Copy_file_range
Preadv2
Pwritev2
)