Working hello world with fasm2
This commit is contained in:
parent
dceb330571
commit
03b272d91e
1
.gitignore
vendored
1
.gitignore
vendored
@ -0,0 +1 @@
|
|||||||
|
build/**
|
30
scripts/build.ps1
Normal file
30
scripts/build.ps1
Normal 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
|
82
scripts/helpers/incremental_checks.ps1
Normal file
82
scripts/helpers/incremental_checks.ps1
Normal 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
20
scripts/helpers/ini.ps1
Normal 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
67
scripts/helpers/misc.ps1
Normal 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
38
source/hello.asm
Normal 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'
|
Loading…
Reference in New Issue
Block a user