Compare commits

..

7 Commits
v0.3.0 ... main

Author SHA1 Message Date
c7402b8dab msp430-asm: use macro_rules! instead of nightly macro syntax.
It may be nice, but y'know what's nicer? Building on stable.
2024-08-05 12:38:17 -05:00
0614e17b73 ast: Consistent constant folding. 2024-08-05 12:36:27 -05:00
5a1112db8f Update shellcode.asm 2024-07-31 11:59:45 -05:00
822c7f3700 parser: Parse char immediates into Expr::Number 2024-07-31 11:36:37 -05:00
d4c5005d8a Remove dependency on nightly Rust 2024-07-31 10:43:58 -05:00
45b8fa5c8b lexer: Remove redundant imports 2024-03-01 04:35:17 -06:00
dbc5a5fb69 Merge pull request 'v0.3.0' (#1) from v0.3.0 into main
Major rewrite to support new features. Should behave identically to v0.2.0 for any previously compatible source files, except the `.byte` and `.bytes` aliases for `.word` and `.words` have been removed, as has `.strings`

Reviewed-on: #1
2024-02-01 20:11:01 +00:00
7 changed files with 56 additions and 35 deletions

View File

@ -1,7 +1,6 @@
// This example contains information adapted from the MSPGCC project's documentation. // This example contains information adapted from the MSPGCC project's documentation.
// As such, it is licensed under the GPL, to the extent that such a thing is possible. // As such, it is licensed under the GPL, to the extent that such a thing is possible.
// https://mspgcc.sourceforge.net/manual/ln16.html // https://mspgcc.sourceforge.net/manual/ln16.html
#![feature(decl_macro)]
fn main() { fn main() {
println!("Hello, world!") println!("Hello, world!")

View File

@ -1,5 +1,4 @@
//! Helper library for msp430-asm //! Helper library for msp430-asm
#![feature(decl_macro)]
pub mod split_twice { pub mod split_twice {
/// Slices a collection into a beginning, middle, and end, based on two unordered indices /// Slices a collection into a beginning, middle, and end, based on two unordered indices
pub trait SplitTwice<'t> { pub trait SplitTwice<'t> {
@ -63,30 +62,51 @@ pub mod cursor {
use std::fmt::{Arguments, Display}; use std::fmt::{Arguments, Display};
/// Moves to the {line}th previous line /// Moves to the {line}th previous line
pub macro previous($line:literal) { #[macro_export]
csi!("{}F", $line) macro_rules! previous {
($line:literal) => {
csi!("{}F", $line)
};
} }
/// Injects a Command Sequence Introducer /// Injects a Command Sequence Introducer
pub macro csi($($t:tt)*) { #[macro_export]
format_args!("\x1b[{}", format_args!($($t)*)) macro_rules! csi {
($($t:tt)*) => {
format_args!("\x1b[{}", format_args!($($t)*))
};
} }
/// Formats the args with a foreground [Color] /// Formats the args with a foreground [Color]
pub macro fg($fg:expr, $($t:tt)*) { #[macro_export]
Colorized::new(Some($fg), None, format_args!($($t)*)) macro_rules! fg {
($fg:expr, $($t:tt)*) => {
Colorized::new(Some($fg), None, format_args!($($t)*))
};
} }
/// Formats the args with a background [Color] /// Formats the args with a background [Color]
pub macro bg($bg:expr, $(t:tt)*) { #[macro_export]
Colorized::new(None, Some($bg), format_args!($($t)*)) macro_rules! bg {
($bg:expr, $(t:tt)*) => {
Colorized::new(None, Some($bg), format_args!($($t)*))
};
} }
/// Formats the args with both a foreground and background [Color] /// Formats the args with both a foreground and background [Color]
pub macro color($fg:expr, $bg:expr, $($t:tt)*) { #[macro_export]
Colorized::new(Some($fg), Some($bg), format_args!($($t)*)) macro_rules! color {
($fg:expr, $bg:expr, $($t:tt)*) => {
Colorized::new(Some($fg), Some($bg), format_args!($($t)*))
}
} }
pub use bg;
pub use color;
pub use csi;
pub use fg;
pub use previous;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Color { pub enum Color {
#[default] #[default]

View File

@ -1,7 +1,6 @@
// © 2023-2024 John Breaux // © 2023-2024 John Breaux
//See LICENSE.md for license //See LICENSE.md for license
//! Simple frontend for the assembler //! Simple frontend for the assembler
#![feature(decl_macro)]
use argp::parse_args_or_exit; use argp::parse_args_or_exit;
use libmsp430::{ use libmsp430::{
assembler::Assemble, assembler::Assemble,
@ -66,14 +65,16 @@ mod repl {
use std::io::{stderr, Write}; use std::io::{stderr, Write};
/// Formats the line number /// Formats the line number
macro linenr($n: expr) { macro_rules! linenr {
format_args!("{:4}: ", $n) ($n: expr) => {
format_args!("{:4}: ", $n)
};
} }
/// [println], but without the newline /// [println], but without the newline
macro printfl ($($x: expr),+) { macro_rules! printfl {($($x: expr),+) => {
{print!($($x),+); let _ = ::std::io::stdout().flush();} {print!($($x),+); let _ = ::std::io::stdout().flush();}
} }}
/// Runs the read-evaluate-print loop /// Runs the read-evaluate-print loop
pub fn repl(buf: &mut String) -> Result<(), Box<dyn Error>> { pub fn repl(buf: &mut String) -> Result<(), Box<dyn Error>> {

View File

@ -1,13 +1,11 @@
; © 2023-2024 John Breaux ; © 2023-2024 John Breaux
; Comtains spoilers for Microcorruption Halifax! Be warned! ; Comtains spoilers for Microcorruption Halifax! Be warned!
; just hash the first 0x140 B and stick them in memory
const: const:
.define msize 0x1 ; length of each hash in bytes .define msize 0x1 ; length of each hash in bytes
.define hsize 0x3 ; bytes kept per hash (only needs to be 3 to determine 1 byte of sram) .define hsize 0x3 ; bytes kept per hash (only needs to be 3 to determine 1 byte of sram)
.define sr_len 0x140 ; number of bytes in sram to dump .define sr_len 0x140 ; number of bytes in sram to dump
.define ha_len 0x3c0 ; number of bytes in hash array (hsize * sr_len)
.define haddr 0x7000 ; address of the big hash array .define haddr 0x7000 ; address of the big hash array
.define iaddr 0x8000 ; address of the sram input buffer .define iaddr 0x8000 ; address of the sram input buffer
.define kaddr 0x9000 ; address of the key buffer .define kaddr 0x9000 ; address of the key buffer
@ -24,7 +22,7 @@ external_func:
.define puts #0x4586 .define puts #0x4586
; memcpy(void *dest, void *src, size_t len) ; memcpy(void *dest, void *src, size_t len)
.define memcpy #0x45a4 .define memcpy #0x45a4
; sha256_internal(void * sram_addr, size_t sr_len, void * sha_buf) ; sha256_internal(void *sram_addr, size_t sr_len, void * sha_buf)
.define sha256_internal #0x45b6 .define sha256_internal #0x45b6
; memset(void* buf, char value, size_t length) ; memset(void* buf, char value, size_t length)
.define memset #0x45c8 .define memset #0x45c8
@ -35,10 +33,10 @@ get_sram_hashes:
mov #haddr, r13 ; set destination to 0x8000 mov #haddr, r13 ; set destination to 0x8000
sr_loop: sr_loop:
mov r11, r15 ; mov addr r15 mov r11, r15 ; mov addr r15
call sha256_internal ; <sha256_internal> call sha256_internal ; sha256_internal (i, msize, haddr + i * hsize)
add #hsize, r13 ; keep 3 bytes of the output add #hsize, r13 ; keep 3 bytes of the output
inc r11 ; inc r11 inc r11 ; inc r11
cmp #sr_len, r11 ; do that 0x1000 times cmp #sr_len, r11 ; do that sram_len times
jnc sr_loop jnc sr_loop
print_hex: print_hex:
@ -53,27 +51,27 @@ print_hex:
clrc clrc
and #0xf, r14 and #0xf, r14
mov.b HEX_LUT(r15), r15 mov.b HEX_LUT(r15), r15
call putchar ; <putchar> call putchar ; putchar (HEX_LUT[haddr[i] >> 4])
mov.b HEX_LUT(r14), r15 mov.b HEX_LUT(r14), r15
call putchar ; <putchar> call putchar ; putchar (HEX_LUT[haddr[i] & 0xf])
inc r11 ; inc r11 inc r11
cmp #ha_len, r11 ; do that sram_length*3 times cmp #sr_len * hsize, r11 ; do that sram_length * hash_size times
jnc ph_loop jnc ph_loop
mov.b #0xa, r15 ; '\n' mov.b #'\n', r15 ; '\n'
call #0x4578 ; putchar ('\n') call putchar ; putchar ('\n')
take_input: take_input:
mov #sr_len, r14 mov #sr_len, r14
mov #iaddr, r15 mov #iaddr, r15
call getsn ; <getsn> call getsn ; getsn (iaddr, sr_len)
check_all_passwords: check_all_passwords:
;for i in 0..sr_len: ;for i in 0..sr_len:
clr r9 clr r9
pw_loop: pw_loop:
; memcpy(kaddr, iaddr + i, len) ; memcpy (kaddr, iaddr + i, len)
mov #0x10, r13 mov #0x10, r13
mov #iaddr, r14 mov #iaddr, r14
add r9, r14 add r9, r14
@ -84,7 +82,7 @@ check_all_passwords:
push #0x42 push #0x42
call INT call INT
add #4, sp add #4, sp
; INT(7f) ; INT (7f)
unlock7f: unlock7f:
push #0 push #0
push #0 push #0

View File

@ -5,7 +5,7 @@
pub mod token; pub mod token;
use self::token::{Special, TokenKind, *}; use self::token::*;
use crate::span::Span; use crate::span::Span;
use std::{ use std::{
iter::Peekable, iter::Peekable,

View File

@ -173,6 +173,10 @@ impl<'t> Parser<'t> {
self.take(); self.take();
Expr::Number(n) Expr::Number(n)
} }
Kind::Char(c) => {
self.take();
Expr::Number(c as _)
}
Kind::Identifier => { Kind::Identifier => {
self.take(); self.take();
Expr::Ident(lexeme) Expr::Ident(lexeme)

View File

@ -645,13 +645,12 @@ pub mod canonical {
Expr::Number(tail) Expr::Number(tail)
} }
Expr::Binary(head, tails) => { Expr::Binary(head, tails) => {
let mut tails = tails.into_iter().map(|(op, tail)| (op, tail.to_canonical()));
let mut head = match head.to_canonical() { let mut head = match head.to_canonical() {
Expr::Number(n) => n, Expr::Number(n) => n,
head => return Expr::Binary(head.into(), tails), head => return Expr::Binary(head.into(), tails.collect()),
}; };
let mut tails = tails.into_iter();
for (op, tail) in &mut tails { for (op, tail) in &mut tails {
let tail = tail.to_canonical();
// If the canonical tail isn't a number, rebuild and return // If the canonical tail isn't a number, rebuild and return
let Expr::Number(tail) = tail else { let Expr::Number(tail) = tail else {
return Expr::Binary( return Expr::Binary(