Working hello world with fasm2

This commit is contained in:
Edward R. Gonzalez 2024-11-25 00:05:27 -05:00
parent dceb330571
commit 03b272d91e
6 changed files with 238 additions and 0 deletions

1
.gitignore vendored
View File

@ -0,0 +1 @@
build/**

30
scripts/build.ps1 Normal file
View File

@ -0,0 +1,30 @@
$misc = join-path $PSScriptRoot 'helpers/misc.ps1'
. $misc
$path_root = git rev-parse --show-toplevel
$path_build = join-path $path_root 'build'
$path_scripts = join-path $path_root 'scripts'
$path_source = join-path $path_root 'source'
$path_toolchain = join-path $path_root 'toolchain'
$path_fasm = join-path $path_toolchain 'fasmw17332'
$path_fasmg = join-path $path_toolchain 'fasmg.kl0e'
$path_fasm2 = join-path $path_toolchain 'fasm2'
$fasm = join-path $path_fasm 'FASM.EXE'
$fasmg = join-path $path_fasmg 'fasmg.exe'
# $fasm2 = join-path $path_fasm2 "fasmg.exe -iInclude('fasm2.inc')"
verify-path $path_build
push-location $path_build
function build-hello
{
$env:include = join-path $path_fasm2 'include'
$asm_hello = join-path $path_source 'hello.asm'
$exe_hello = 'hello.exe'
& $fasmg $asm_hello $exe_hello
}
build-hello
pop-location

View File

@ -0,0 +1,82 @@
# This is meant to be used with build.ps1, and is not a standalone script.
function check-FileForChanges
{
param(
[Parameter(Mandatory=$true)]
[string]$path_file
)
if (-not (Test-Path $path_file -PathType Leaf)) {
Write-Error "The provided path is not a valid file: $path_file"
return $false
}
$file_name = Split-Path $path_file -Leaf
$path_csv = Join-Path $path_build ($file_name + "_file_hash.csv")
$csv_file_hash = $null
if (Test-Path $path_csv) {
$csv_file_hash = Import-Csv $path_csv | Select-Object -ExpandProperty value
}
$current_hash_info = Get-FileHash -Path $path_file -Algorithm MD5
$current_file_hash = $current_hash_info.Hash
# Save the current hash to the CSV
[PSCustomObject]@{
name = $path_file
value = $current_file_hash
} | Export-Csv $path_csv -NoTypeInformation
if ($csv_file_hash -and $csv_file_hash -eq $current_file_hash) {
return $false
} else {
return $true
}
}
# Check to see if the module has changed files since the last build
function check-ModuleForChanges
{
param( [string]$path_module, [array]$excludes )
$module_name = split-path $path_module -leaf
$path_csv = Join-Path $path_build ("module_" + $module_name + "_hashes.csv")
$csv_file_hashes = $null
if ( test-path $path_csv ) {
$csv_file_hashes = @{}
import-csv $path_csv | foreach-object {
$csv_file_hashes[ $_.name ] = $_.value
}
}
$file_hashes = @{}
get-childitem -path $path_module -file -Exclude $excludes -Recurse | foreach-object {
$id = $_.fullname
$hash_info = get-filehash -path $id -Algorithm MD5
$file_hashes[ $id ] = $hash_info.Hash
}
$file_hashes.GetEnumerator() | foreach-object { [PSCustomObject]$_ } |
export-csv $path_csv -NoTypeInformation
if ( -not $csv_file_hashes ) { return $true }
if ( $csv_file_hashes.Count -ne $file_hashes.Count ) { return $true }
foreach ( $key in $csv_file_hashes.Keys ) {
if ( $csv_file_hashes[ $key ] -ne $file_hashes[ $key ] ) {
return $true
}
}
return $false
}
function mark-ModuleDirty {
param( [string]$path_module )
$module_name = split-path $path_module -leaf
$path_csv = Join-Path $path_build ("module_" + $module_name + "_hashes.csv")
remove-item -Force -Path $path_csv
}

20
scripts/helpers/ini.ps1 Normal file
View File

@ -0,0 +1,20 @@
# This is meant to be used with build.ps1, and is not a standalone script.
function Get-IniContent { param([ string]$filePath )
$ini = @{}
$currentSection = $null
switch -regex -file $filePath
{
"^\[(.+)\]$" {
$currentSection = $matches[1].Trim()
$ini[$currentSection] = @{}
}
"^(.+?)\s*=\s*(.*)" {
$key, $value = $matches[1].Trim(), $matches[2].Trim()
if ($null -ne $currentSection) {
$ini[$currentSection][$key] = $value
}
}
}
return $ini
}

67
scripts/helpers/misc.ps1 Normal file
View File

@ -0,0 +1,67 @@
function clone-gitrepo { param( [string] $path, [string] $url )
if (test-path $path) {
# git -C $path pull
}
else {
Write-Host "Cloning $url ..."
git clone $url $path
}
}
function Update-GitRepo
{
param( [string] $path, [string] $url, [string] $build_command )
if ( $build_command -eq $null ) {
write-host "Attempted to call Update-GitRepo without build_command specified"
return
}
$repo_name = $url.Split('/')[-1].Replace('.git', '')
$last_built_commit = join-path $path_build "last_built_commit_$repo_name.txt"
if ( -not(test-path -Path $path))
{
write-host "Cloining repo from $url to $path"
git clone $url $path
write-host "Building $url"
push-location $path
& "$build_command"
pop-location
git -C $path rev-parse HEAD | out-file $last_built_commit
$script:binaries_dirty = $true
write-host
return
}
git -C $path fetch
$latest_commit_hash = git -C $path rev-parse '@{u}'
$last_built_hash = if (Test-Path $last_built_commit) { Get-Content $last_built_commit } else { "" }
if ( $latest_commit_hash -eq $last_built_hash ) {
write-host
return
}
write-host "Build out of date for: $path, updating"
write-host 'Pulling...'
git -C $path pull
write-host "Building $url"
push-location $path
& $build_command
pop-location
$latest_commit_hash | out-file $last_built_commit
$script:binaries_dirty = $true
write-host
}
function verify-path { param( $path )
if (test-path $path) {return}
new-item -ItemType Directory -Path $path
return
}

38
source/hello.asm Normal file
View File

@ -0,0 +1,38 @@
include 'fasm2.inc'
format PE64 console
entry main
section '.data' data readable writeable
message db 'Hello World!', 13, 10
message_len = $ - message
written dq ?
section '.text' code readable executable
main:
sub rsp, 40 ; 32 + 8 for alignment
mov ecx, -11 ; STD_OUTPUT_HANDLE
call [GetStdHandle]
mov rcx, rax ; Handle
lea rdx, [message] ; Buffer
mov r8, message_len ; Length
lea r9, [written] ; Bytes written
push 0 ; Reserved parameter
sub rsp, 32 ; Shadow space
call [WriteConsoleA]
add rsp, 40 ; Cleanup stack + reserved param
xor ecx, ecx ; Exit code 0
call [ExitProcess]
section '.idata' import data readable
library kernel32,'KERNEL32.DLL'
include 'win64a.inc'
import kernel32,\
GetStdHandle,'GetStdHandle',\
WriteConsoleA,'WriteConsoleA',\
ExitProcess,'ExitProcess'