x86_64 call & ret
This commit is contained in:
@@ -8,6 +8,8 @@ pub struct Asm {
|
|||||||
pub enum Instr {
|
pub enum Instr {
|
||||||
Mov { dst: RegMode, src: RegImm },
|
Mov { dst: RegMode, src: RegImm },
|
||||||
Int { code: u8 },
|
Int { code: u8 },
|
||||||
|
Call(Symbol),
|
||||||
|
Ret,
|
||||||
Syscall,
|
Syscall,
|
||||||
Lea { dst: RegMode, sym: Symbol },
|
Lea { dst: RegMode, sym: Symbol },
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,6 +106,15 @@ impl Encoder {
|
|||||||
self.data.extend([0x0f, 0x05])
|
self.data.extend([0x0f, 0x05])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn call(&mut self, sym: Symbol) {
|
||||||
|
self.data.push(0xe8);
|
||||||
|
self.sym_offset4(sym);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ret(&mut self) {
|
||||||
|
self.data.push(0xc3);
|
||||||
|
}
|
||||||
|
|
||||||
/// inserts a 32 bit offset from a symbol
|
/// inserts a 32 bit offset from a symbol
|
||||||
pub fn sym_offset4(&mut self, sym: Symbol) {
|
pub fn sym_offset4(&mut self, sym: Symbol) {
|
||||||
let Some(addr) = self.sym_tab.get(sym) else {
|
let Some(addr) = self.sym_tab.get(sym) else {
|
||||||
@@ -123,6 +132,8 @@ impl Encoder {
|
|||||||
Instr::Int { code } => self.int(code),
|
Instr::Int { code } => self.int(code),
|
||||||
Instr::Syscall => self.syscall(),
|
Instr::Syscall => self.syscall(),
|
||||||
Instr::Lea { dst, sym } => self.lea(dst, sym),
|
Instr::Lea { dst, sym } => self.lea(dst, sym),
|
||||||
|
Instr::Call(sym) => self.call(sym),
|
||||||
|
Instr::Ret => self.ret(),
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,18 @@ pub fn run() {
|
|||||||
let mut program = Program::<X86_64>::default();
|
let mut program = Program::<X86_64>::default();
|
||||||
let text = b"Hello world!\n";
|
let text = b"Hello world!\n";
|
||||||
let text_sym = program.ro_data(text);
|
let text_sym = program.ro_data(text);
|
||||||
|
let text2 = "世界、こんにちは!\n";
|
||||||
|
let text_sym2 = program.ro_data(text2);
|
||||||
|
let hello2 = program.func([BInstr::Asm(Asm {
|
||||||
|
instrs: vec![
|
||||||
|
mov(ax, 1),
|
||||||
|
mov(di, 1),
|
||||||
|
lea(rsi, text_sym2),
|
||||||
|
mov(dx, text2.len() as u64),
|
||||||
|
Instr::Syscall,
|
||||||
|
Instr::Ret,
|
||||||
|
],
|
||||||
|
})]);
|
||||||
let entry = program.func([BInstr::Asm(Asm {
|
let entry = program.func([BInstr::Asm(Asm {
|
||||||
instrs: vec![
|
instrs: vec![
|
||||||
mov(ax, 1),
|
mov(ax, 1),
|
||||||
@@ -15,6 +27,7 @@ pub fn run() {
|
|||||||
lea(rsi, text_sym),
|
lea(rsi, text_sym),
|
||||||
mov(dx, text.len() as u64),
|
mov(dx, text.len() as u64),
|
||||||
Instr::Syscall,
|
Instr::Syscall,
|
||||||
|
Instr::Call(hello2),
|
||||||
mov(ax, 0x3c),
|
mov(ax, 0x3c),
|
||||||
mov(di, 39),
|
mov(di, 39),
|
||||||
Instr::Syscall,
|
Instr::Syscall,
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ pub enum Instr<A: Arch> {
|
|||||||
Set { dst: VarId, src: Vec<u8> },
|
Set { dst: VarId, src: Vec<u8> },
|
||||||
Call { dst: FnId, args: Vec<VarId> },
|
Call { dst: FnId, args: Vec<VarId> },
|
||||||
Copy { dst: VarId, src: VarId },
|
Copy { dst: VarId, src: VarId },
|
||||||
Free(VarId),
|
|
||||||
Asm(A::Asm),
|
Asm(A::Asm),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
BIN
Binary file not shown.
Reference in New Issue
Block a user