gitweb on Svarog
projekti pod git sistemom za održavanje verzija -- projects under the git version control system
summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 273705b)
raw | patch | inline | side by side (parent: 273705b)
author | Doni Pracner <quinnuendo@gmail.com> | |
Fri, 19 Jul 2019 15:59:24 +0000 (17:59 +0200) | ||
committer | Doni Pracner <quinnuendo@gmail.com> | |
Fri, 19 Jul 2019 15:59:24 +0000 (17:59 +0200) |
43 files changed:
diff --git a/build.xml b/build.xml
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,291 @@
+<project name="asm2wsl" default="all">
+ <description>
+ Builder script for asm2wsl and related tools
+ </description>
+
+ <!-- use this file for any custom local needs -->
+ <property file="custom.properties"/>
+ <property environment="env"/>
+ <!-- try and detect the fermat.dir based on the operating system
+ should be set as a custom value in "custom.properties"
+ if it's in a non default location.
+ -->
+ <condition property="fermat.dir" value="C:\fermat3">
+ <os family="windows" />
+ </condition>
+
+ <condition property="fermat.dir" value="${user.home}/fermat3">
+ <not><os family="windows" /></not>
+ </condition>
+
+ <property name="java.encoding" value="utf-8" />
+ <taskdef resource="net/sf/antcontrib/antlib.xml"/>
+
+ <!-- **************************************** -->
+ <!-- main variables that can be altered in the
+ properties file or through command line switches.
+ -->
+ <!-- **************************************** -->
+
+ <!-- when using multiple threads there is a problem with logging!-->
+ <property name="global.max.threads" value="1" />
+
+ <property name="asm2wsl.class.dir" value="bin" />
+ <property name="asm2wsl.src.dir" value="src" />
+ <property name="asm2wsl.options" value="" />
+
+ <property name="asm.extension" value="asm" />
+
+ <property name="res.dir" value="res" />
+ <property name="dist.dir" value="dist" />
+
+ <property name="samples.main.dir" value="samples" />
+ <property name="samples.temp.dir" value="temp" />
+
+ <property name="transf.wsl.file" value="src-wsl/transf-min.wsl" />
+ <property name="transf.wsl.ext" value="_t.wsl" />
+ <!-- args can be used to send additional arguments to a script -->
+ <property name="transf.wsl.args" value="" />
+
+ <property name="metrics.wsl.file" value="src-wsl/metrics_csv.wsl" />
+ <property name="metrics.extension" value=".met" />
+
+ <property name="tests.dir" value="tests" />
+
+ <property name="log.dir" value="${basedir}/logs" />
+ <property name="log.file.transformations" value="${log.dir}/transformations" />
+ <property name="log.file.asm2wsl" value="${log.dir}/asm2wsl" />
+ <property name="log.file.tests.t" value="${log.dir}/tests-wsl" />
+
+ <!-- **************************************** -->
+ <!-- patterns -->
+ <!-- **************************************** -->
+
+ <patternset id="non.transformed.sources">
+ <include name="**/*.wsl"/>
+ <exclude name="**/*${transf.wsl.ext}"/>
+ </patternset>
+
+ <patternset id="transformed.sources">
+ <include name="**/*${transf.wsl.ext}"/>
+ </patternset>
+
+ <!-- **************************************** -->
+ <!-- general tasks -->
+ <!-- **************************************** -->
+
+ <target name="init" depends="init-time">
+ <mkdir dir="${asm2wsl.class.dir}"/>
+ <mkdir dir="${samples.temp.dir}"/>
+ <mkdir dir="${log.dir}"/>
+ <mkdir dir="${dist.dir}"/>
+ <copy todir="${samples.temp.dir}">
+ <fileset dir="${samples.main.dir}">
+ <include name="*.${asm.extension}"/>
+ </fileset>
+ </copy>
+ </target>
+
+ <target name="init-time">
+ <tstamp>
+ <format property="time" pattern="yy-MM-dd--HH-mm-ss"/>
+ </tstamp>
+ </target>
+
+ <target name="all" depends='asm2wsl-samples,wsl-transf-samples'
+ description="build the tools, run them on the samples to check">
+
+ </target>
+
+ <target name="clean" description="clean up all the generated content">
+ <delete includeemptydirs="true">
+ <fileset dir="${asm2wsl.class.dir}"/>
+ <fileset dir="${samples.temp.dir}"/>
+ <fileset dir="${log.dir}"/>
+ </delete>
+ </target>
+
+ <!-- **************************************** -->
+ <!-- asm2wsl related tasks -->
+ <!-- **************************************** -->
+
+
+ <target name="build" depends="init" description="build the asm2wsl tool">
+ <javac srcdir="${asm2wsl.src.dir}" destdir="${asm2wsl.class.dir}" includeAntRuntime='no' debug='on'/>
+ <copy todir="${asm2wsl.class.dir}">
+ <fileset dir="${res.dir}"/>
+ </copy>
+ </target>
+
+ <target name="asm2wsl">
+ <echo message="${filename}" />
+ <java classpath="${asm2wsl.class.dir}:${res.dir}" classname="asm2wsl">
+ <arg line="${asm2wsl.options}" />
+ <arg value="${filename}" />
+ </java>
+ </target>
+
+ <target name="asm2wsl-samples" depends="build,init-time" description="run the asm2wsl tool on the samples">
+ <record name="${log.file.asm2wsl}${time}.txt" emacsmode="true" />
+ <echo>Used options:${asm2wsl.options}</echo>
+ <foreach param="filename" target="asm2wsl" parallel="true" maxthreads="${global.max.threads}">
+ <path>
+ <fileset dir='${samples.temp.dir}'>
+ <include name="*.${asm.extension}"/>
+ </fileset>
+ </path>
+ </foreach>
+ <record name="${log.file.asm2wsl}${time}.txt" action="stop" />
+ <copy file="${log.file.asm2wsl}${time}.txt" tofile="${log.file.asm2wsl}.txt"/>
+ </target>
+
+ <!-- **************************************** -->
+ <!-- wsl related tasks -->
+ <!-- **************************************** -->
+
+ <target name="wsl-run" >
+ <property name="args" value=""/>
+ <property name="wslrun.workdir" value=""/>
+ <exec executable="${fermat.dir}/bin/wsl" inputstring="${inputstring}"
+ dir="${wslrun.workdir}" >
+ <env key="PATH" path="${fermat.dir}/bin:${env.PATH}"/>
+ <env key="FermaT" path="${fermat.dir}" />
+ <env key="SCHEME_LIBRARY_PATH" path="${fermat.dir}/slib/" />
+ <env key="SCM_INIT_PATH" path="${fermat.dir}/scm/Init5e7.scm" />
+ <arg line="${filename} ${args}"/>
+ </exec>
+ </target>
+
+ <target name="wsl-transf"
+ description="transform (simplify) a single wsl file generated by mjc2wsl">
+ <stopwatch name="transf-${transf.filename}" action="start"/>
+ <antcall target="wsl-run">
+ <param name="filename" value="${transf.wsl.file}" />
+ <param name="args" value="${transf.wsl.args} ${transf.filename}" />
+ </antcall>
+ <record name="${transf.filename}-time.txt" action="start" emacsmode="true"/>
+ <stopwatch name="transf-${transf.filename}" action="total"/>
+ <record name="${transf.filename}-time.txt" action="stop"/>
+ </target>
+
+ <target name="wsl-transf-samples" depends="init"
+ description="transform (simplify) the wsl files generated by mjc2wsl" >
+ <record name="${log.file.transformations}${time}.txt" emacsmode="true" />
+ <foreach param="transf.filename" target="wsl-transf" parallel="true" maxthreads="${global.max.threads}">
+ <path>
+ <fileset dir='${samples.temp.dir}'>
+ <patternset refid="non.transformed.sources"/>
+ <depth max="0"/>
+ </fileset>
+ </path>
+ </foreach>
+ <record name="${log.file.transformations}${time}.txt" action="stop" />
+ <copy file="${log.file.transformations}${time}.txt" tofile="${log.file.transformations}.txt"/>
+ </target>
+
+ <!-- **************************************** -->
+ <!-- metrics -->
+ <!-- **************************************** -->
+
+ <target name="metrics-compare-wsl">
+ <basename property="metrics.temp.name" file="${metrics.run.filename}" suffix="${transf.wsl.ext}"/>
+ <dirname property="metrics.temp.dir" file="${metrics.run.filename}"/>
+ <antcall target="wsl-run">
+ <param name="filename" value="${metrics.wsl.file}" />
+ <param name="args" value="-o ${metrics.temp.dir}/${metrics.temp.name}${metrics.extension} -c ${metrics.temp.dir}/${metrics.temp.name}.wsl ${metrics.temp.dir}/${metrics.temp.name}${transf.wsl.ext}" />
+
+ </antcall>
+
+ </target>
+
+ <target name="metrics-samples-compare-wsl" depends="init"
+ description="metrics on transformed wsl files (csv file)" >
+
+ <antcall target="wsl-run">
+ <param name="filename" value="${metrics.wsl.file}" />
+ <param name="args" value="-o ${samples.temp.dir}/0000-header${metrics.extension} -HC" />
+
+ </antcall>
+
+ <foreach param="metrics.run.filename" target="metrics-compare-wsl" parallel="true" maxthreads="${global.max.threads}">
+ <path>
+ <fileset dir='${samples.temp.dir}'>
+ <patternset refid="transformed.sources"/>
+ </fileset>
+ </path>
+ </foreach>
+
+ <concat destfile="${samples.temp.dir}/metrics-wsl-compare.csv">
+ <fileset dir="${samples.temp.dir}" includes="*${metrics.extension}"/>
+ </concat>
+ </target>
+
+ <!-- **************************************** -->
+ <!-- Testing tasks -->
+ <!-- **************************************** -->
+
+ <target name="init-compare">
+ <mkdir dir="${samples.temp.dir}/outputs"/>
+ </target>
+
+ <target name="test-w-wt">
+
+ <basename property="file.out" file="${inputfile}" suffix=".txt"/>
+
+ <exec executable="${fermat.dir}/bin/wsl"
+ input="${inputfile}"
+ error="${samples.temp.dir}/outputs/${file.out}.errwsl"
+ output="${samples.temp.dir}/outputs/${file.out}.outwsl" >
+ <env key="PATH" path="${fermat.dir}/bin:${env.PATH}"/>
+ <env key="FermaT" path="${fermat.dir}" />
+ <env key="SCHEME_LIBRARY_PATH" path="${fermat.dir}/slib/" />
+ <env key="SCM_INIT_PATH" path="${fermat.dir}/scm/Init5e7.scm" />
+ <arg value="${file.dir}/${file.name}.wsl"/>
+ </exec>
+
+ <exec executable="${fermat.dir}/bin/wsl"
+ input="${inputfile}"
+ error="${samples.temp.dir}/outputs/${file.out}.errwslt"
+ output="${samples.temp.dir}/outputs/${file.out}.outwslt" >
+ <env key="PATH" path="${fermat.dir}/bin:${env.PATH}"/>
+ <env key="FermaT" path="${fermat.dir}" />
+ <env key="SCHEME_LIBRARY_PATH" path="${fermat.dir}/slib/" />
+ <env key="SCM_INIT_PATH" path="${fermat.dir}/scm/Init5e7.scm" />
+ <arg value="${file.dir}/${file.name}${transf.wsl.ext}"/>
+ </exec>
+
+ <exec executable="perl">
+ <arg value="lib/compare-w-wt.pl"/>
+ <arg value="${file.dir}/outputs"/>
+ <arg value="${file.out}"/>
+ </exec>
+ </target>
+
+ <target name="test-fn-t">
+ <basename property="file.name" file="${filename}" suffix="${transf.wsl.ext}"/>
+ <dirname property="file.dir" file="${filename}"/>
+ <foreach param="inputfile" target="test-w-wt" inheritall="true">
+ <path>
+ <fileset dir='${tests.dir}'>
+ <include name="${file.name}*.txt"/>
+ </fileset>
+ </path>
+ </foreach>
+ </target>
+
+ <target name="test-all-t" depends="init-compare,init-time"
+ description="Run all the tests from the test directory to compare WSL and transformations" >
+ <record name="${log.file.tests.t}${time}.txt" emacsmode="true" />
+ <foreach param="filename" target="test-fn-t">
+ <path>
+ <fileset dir='${samples.temp.dir}'>
+ <include name="*${transf.wsl.ext}"/>
+ </fileset>
+ </path>
+ </foreach>
+ <record name="${log.file.tests.t}${time}.txt" action="stop" />
+ <move file="${log.file.tests.t}.txt" tofile="${log.file.tests.t}-previous.txt" failonerror="false"/>
+ <copy file="${log.file.tests.t}${time}.txt" tofile="${log.file.tests.t}.txt"/>
+ </target>
+
+</project>
diff --git a/lib/compare-w-wt.pl b/lib/compare-w-wt.pl
--- /dev/null
+++ b/lib/compare-w-wt.pl
@@ -0,0 +1,44 @@
+#!/usr/bin/perl
+#
+# test if the outputs are the same from two versions of
+# WSL programs - the original and the transformation
+
+sub read_file($) {
+ my ($file) = @_;
+ my $in;
+ open($in, $file) or die "Cannot read $file: $!\n";
+ my $data = join("", <$in>);
+ close($in);
+ return($data);
+}
+
+# quit unless we have the correct number of command-line args
+$num_args = $#ARGV + 1;
+if ($num_args != 2) {
+ print "\nUsage: compare-w-wt.pl directory base_filename \n";
+ exit;
+}
+
+$dir=@ARGV[0];
+$base=@ARGV[1];
+
+$outw = read_file("$dir/$base.outwsl");
+$outwt = read_file("$dir/$base.outwslt");
+
+#print "inputs:\n";
+#print "$outm\n--\n$outw\n\n";
+
+#process the WSL output to remove comments
+for ($outw, $outwt) {
+ s/^.*Starting Execution...//s;
+ s/^.*?\n.*?\n//s;
+ s/Execution time:.*//s;
+}
+
+if ($outw eq $outwt) {
+ print "$base - OK\n";
+} else {
+ print "$base - difference detected!:\n";
+ print "$outw###\n--\n$outwt###\n";
+ die();
+}
\ No newline at end of file
diff --git a/samples-with-macros/array-sum-input.asm b/samples-with-macros/array-sum-input.asm
--- /dev/null
@@ -0,0 +1,194 @@
+.model small\r
+;make a sum of an array - version with loading values\r
+;predefined array size\r
+\r
+;#macro-commands-start\r
+end_execution macro\r
+; finish the execution\r
+ mov ax, 4c02h\r
+ int 21h\r
+endm \r
+\r
+print_str macro s\r
+; print a s string on screen\r
+ push ax\r
+ push dx \r
+ mov dx, offset s\r
+ mov ah, 09\r
+ int 21h\r
+ pop dx\r
+ pop ax\r
+endm\r
+\r
+inttostr macro num1 str1\r
+; convert num1 to str1\r
+ push ax\r
+ push bx\r
+ push cx\r
+ push dx\r
+ push si\r
+ mov ax, num1\r
+ mov dl, '$'\r
+ push dx\r
+ mov si, 10\r
+itosloop:\r
+ mov dx, 0\r
+ div si\r
+ add dx, 48\r
+ push dx\r
+ cmp ax, 0\r
+ jne itosloop\r
+ \r
+ mov bx, offset str1\r
+itosloopa: \r
+ pop dx\r
+ mov [bx], dl\r
+ inc bx\r
+ cmp dl, '$'\r
+ jne itosloopa\r
+ pop si \r
+ pop dx\r
+ pop cx\r
+ pop bx\r
+ pop ax \r
+endm\r
+\r
+print_num macro num\r
+ ;convert num, print str\r
+ inttostr num,tempStr\r
+ print_str tempStr\r
+endm \r
+\r
+; new line\r
+print_new_line macro\r
+ push ax\r
+ push bx\r
+ push dx\r
+ mov ah,03\r
+ mov bh,0\r
+ int 10h\r
+ inc dh\r
+ mov dl,0\r
+ mov ah,02\r
+ int 10h\r
+ pop dx\r
+ pop bx\r
+ pop ax\r
+endm\r
+\r
+read_num macro num\r
+ read_str tempStr,6\r
+ strtoint tempStr,num\r
+endm\r
+\r
+;read into a buffer, inc the special 0 and 1 bytes\r
+;fixes it into a $ terminated string\r
+read_str macro strbuff, strlen\r
+ LOCAL copystr\r
+ push ax\r
+ push bx\r
+ push cx\r
+ push dx\r
+ push si\r
+ mov bp, sp\r
+ mov dx, offset strbuff\r
+ mov bx, dx\r
+ mov ax, strlen\r
+ mov byte [bx] ,al\r
+ mov ah, 0Ah\r
+ int 21h\r
+ mov si, dx \r
+ mov cl, [si+1] \r
+ mov ch, 0\r
+copystr:\r
+ mov al, [si+2]\r
+ mov [si], al\r
+ inc si\r
+ loop copystr \r
+ mov [si], '$'\r
+ pop si \r
+ pop dx\r
+ pop cx\r
+ pop bx\r
+ pop ax\r
+endm\r
+\r
+;ascii to actual number\r
+strtoint macro inStr,outNum\r
+ LOCAL mainloop,end\r
+ push ax\r
+ push bx\r
+ push cx\r
+ push dx\r
+ push si\r
+ mov bp, sp\r
+ mov bx, offset inStr\r
+ mov ax, 0\r
+ mov cx, 0\r
+ mov si, 10\r
+mainloop:\r
+ mov cl, [bx]\r
+ cmp cl, '$'\r
+ je end\r
+ mul si\r
+ sub cx, 48\r
+ add ax, cx\r
+ inc bx \r
+ jmp mainloop\r
+end:\r
+ mov outNum, ax \r
+ pop si \r
+ pop dx\r
+ pop cx\r
+ pop bx\r
+ pop ax\r
+endm\r
+;#macro-commands-end\r
+\r
+.code\r
+start:\r
+ mov dx, @data\r
+ mov ds, dx \r
+ print_str prompt\r
+ read_num n\r
+ mov ax, 0\r
+ mov cx, n\r
+ cmp maxn, cx\r
+ jae normal\r
+ print_str errorN\r
+ end_execution\r
+normal: \r
+loadloop:\r
+ print_str prompt\r
+ read_num t\r
+ mov ax,t\r
+ mov bx,n\r
+ sub bx,cx\r
+ mov niz[bx],al\r
+ loop loadloop\r
+ print_new_line\r
+ ; now sum up\r
+ mov cx, n\r
+ xor ax,ax\r
+mainloop: \r
+ mov bx, cx\r
+ add al, niz[bx-1] ; get array memeber, byte\r
+ ; store sum in al\r
+ loop mainloop ; end calc if done\r
+ print_num ax\r
+ end_execution\r
+\r
+data segment\r
+n dw 7\r
+t dw 0\r
+maxn dw 20\r
+niz db 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0 \r
+tempStr db " "\r
+prompt db "Number?$"\r
+errorN db "Number too large!$"\r
+ends\r
+end start\r
+\r
+\r
+\r
+\r
diff --git a/samples-with-macros/array-sum-predef.asm b/samples-with-macros/array-sum-predef.asm
--- /dev/null
@@ -0,0 +1,83 @@
+.model small\r
+;make a sum of an array - version with predefined everything\r
+\r
+;#macro-commands-start\r
+end_execution macro\r
+; finish the execution\r
+ mov ax, 4c02h\r
+ int 21h\r
+endm \r
+\r
+print_str macro s\r
+; print a s string on screen\r
+ push ax\r
+ push dx \r
+ mov dx, offset s\r
+ mov ah, 09\r
+ int 21h\r
+ pop dx\r
+ pop ax\r
+endm\r
+\r
+inttostr macro num1 str1\r
+; convert num1 to str1\r
+ push ax\r
+ push bx\r
+ push cx\r
+ push dx\r
+ push si\r
+ mov ax, num1\r
+ mov dl, '$'\r
+ push dx\r
+ mov si, 10\r
+itosloop:\r
+ mov dx, 0\r
+ div si\r
+ add dx, 48\r
+ push dx\r
+ cmp ax, 0\r
+ jne itosloop\r
+ \r
+ mov bx, offset str1\r
+itosloopa: \r
+ pop dx\r
+ mov [bx], dl\r
+ inc bx\r
+ cmp dl, '$'\r
+ jne itosloopa\r
+ pop si \r
+ pop dx\r
+ pop cx\r
+ pop bx\r
+ pop ax \r
+endm\r
+\r
+print_num macro num\r
+ ;convert num, print str\r
+ inttostr num,tempStr\r
+ print_str tempStr\r
+endm\r
+;#macro-commands-end\r
+\r
+.code\r
+start:\r
+ mov dx, @data\r
+ mov ds, dx \r
+ mov cx, n\r
+ mov ax, 0\r
+ mov dx, 0\r
+mainloop: \r
+ mov bx, cx\r
+ add al, niz[bx-1] ; get array memeber, byte\r
+ ; store sum in al\r
+ loop mainloop ; end calc if done\r
+ print_num ax\r
+ end_execution\r
+ \r
+data segment\r
+n dw 7\r
+niz db 1,2,3,4,5,6,7,0 \r
+tempStr db " "\r
+\r
+ends\r
+end start\r
diff --git a/samples-with-macros/gcd-input.asm b/samples-with-macros/gcd-input.asm
--- /dev/null
@@ -0,0 +1,198 @@
+.model small\r
+;greatest common divisor, with input from terminal\r
+data segment\r
+ tempStr db " "\r
+ prompt db "num?$"\r
+ promptr db "RES $"\r
+ m dw 0\r
+ n dw 0\r
+\r
+data ends\r
+;#macro-commands-start\r
+; print a string on screen\r
+print_str macro s\r
+ push ax\r
+ push dx \r
+ mov dx, offset s\r
+ mov ah, 09\r
+ int 21h\r
+ pop dx\r
+ pop ax\r
+endm\r
+\r
+; new line\r
+print_new_line macro\r
+ push ax\r
+ push bx\r
+ push dx\r
+ mov ah,03\r
+ mov bh,0\r
+ int 10h\r
+ inc dh\r
+ mov dl,0\r
+ mov ah,02\r
+ int 10h\r
+ pop dx\r
+ pop bx\r
+ pop ax\r
+endm\r
+\r
+; write a single char\r
+print_char macro c\r
+ push ax \r
+ push dx\r
+ mov ah, 02\r
+ mov dl, c\r
+ int 21h\r
+ pop dx\r
+ pop ax\r
+endm\r
+\r
+; finish the execution\r
+end_execution macro\r
+ mov ax, 4c02h\r
+ int 21h\r
+endm \r
+\r
+; Konvertovanje broja u string\r
+inttostr macro num1 str1\r
+ push ax\r
+ push bx\r
+ push cx\r
+ push dx\r
+ push si\r
+ mov ax, num1\r
+ mov dl, '$'\r
+ push dx\r
+ mov si, 10\r
+petlja2:\r
+ mov dx, 0\r
+ div si\r
+ add dx, 48\r
+ push dx\r
+ cmp ax, 0\r
+ jne petlja2\r
+ \r
+ mov bx, offset str1\r
+petlja2a: \r
+ pop dx\r
+ mov [bx], dl\r
+ inc bx\r
+ cmp dl, '$'\r
+ jne petlja2a\r
+ pop si \r
+ pop dx\r
+ pop cx\r
+ pop bx\r
+ pop ax \r
+endm\r
+\r
+print_num macro num\r
+ inttostr num,tempStr\r
+ print_str tempStr\r
+endm\r
+read_num macro num\r
+ read_str tempStr,6\r
+ strtoint tempStr,num\r
+endm\r
+\r
+;read into a buffer, inc the special 0 and 1 bytes\r
+;fixes it into a $ terminated string\r
+read_str macro strbuff, strlen\r
+ LOCAL copystr\r
+ push ax\r
+ push bx\r
+ push cx\r
+ push dx\r
+ push si\r
+ mov bp, sp\r
+ mov dx, offset strbuff\r
+ mov bx, dx\r
+ mov ax, strlen\r
+ mov byte [bx] ,al\r
+ mov ah, 0Ah\r
+ int 21h\r
+ mov si, dx \r
+ mov cl, [si+1] \r
+ mov ch, 0\r
+copystr:\r
+ mov al, [si+2]\r
+ mov [si], al\r
+ inc si\r
+ loop copystr \r
+ mov [si], '$'\r
+ pop si \r
+ pop dx\r
+ pop cx\r
+ pop bx\r
+ pop ax\r
+endm\r
+\r
+;ascii to actual number\r
+strtoint macro inStr,outNum\r
+ LOCAL mainloop,end\r
+ push ax\r
+ push bx\r
+ push cx\r
+ push dx\r
+ push si\r
+ mov bp, sp\r
+ mov bx, offset inStr\r
+ mov ax, 0\r
+ mov cx, 0\r
+ mov si, 10\r
+mainloop:\r
+ mov cl, [bx]\r
+ cmp cl, '$'\r
+ je end\r
+ mul si\r
+ sub cx, 48\r
+ add ax, cx\r
+ inc bx \r
+ jmp mainloop\r
+end:\r
+ mov outNum, ax \r
+ pop si \r
+ pop dx\r
+ pop cx\r
+ pop bx\r
+ pop ax\r
+endm\r
+;#macro-commands-end\r
+\r
+.code \r
+\r
+start: \r
+ mov ax,@data\r
+ mov ds,ax\r
+ print_str prompt\r
+ read_num m \r
+ print_new_line\r
+ print_str prompt\r
+ read_num n\r
+ print_new_line\r
+\r
+ mov ax,n\r
+ mov bx,m\r
+\r
+compare: \r
+ cmp ax,bx\r
+ je exit ;exit since they're equal\r
+ ja greater\r
+ sub bx,ax\r
+ jmp compare\r
+\r
+greater:\r
+ sub ax,bx\r
+ jmp compare\r
+\r
+exit:\r
+;exit out of the program\r
+ mov n,ax\r
+ print_str promptr\r
+ print_num n\r
+; print out a result\r
+ end_execution\r
+\r
+.stack\r
+end start\r
diff --git a/samples-with-macros/gcd-predef.asm b/samples-with-macros/gcd-predef.asm
--- /dev/null
@@ -0,0 +1,98 @@
+.model small\r
+data segment\r
+ strNZD db " "\r
+data ends\r
+;#macro-commands-start\r
+; print a string on screen\r
+print_str macro s\r
+ push ax\r
+ push dx \r
+ mov dx, offset s\r
+ mov ah, 09\r
+ int 21h\r
+ pop dx\r
+ pop ax\r
+endm\r
+\r
+\r
+; write a single char\r
+print_char macro c\r
+ push ax \r
+ push dx\r
+ mov ah, 02\r
+ mov dl, c\r
+ int 21h\r
+ pop dx\r
+ pop ax\r
+endm\r
+\r
+; finish the execution\r
+end_execution macro\r
+ mov ax, 4c02h\r
+ int 21h\r
+endm \r
+\r
+; Konvertovanje broja u string\r
+inttostr macro num1 str1\r
+ push ax\r
+ push bx\r
+ push cx\r
+ push dx\r
+ push si\r
+ mov ax, num1\r
+ mov dl, '$'\r
+ push dx\r
+ mov si, 10\r
+petlja2:\r
+ mov dx, 0\r
+ div si\r
+ add dx, 48\r
+ push dx\r
+ cmp ax, 0\r
+ jne petlja2\r
+ \r
+ mov bx, offset str1\r
+petlja2a: \r
+ pop dx\r
+ mov [bx], dl\r
+ inc bx\r
+ cmp dl, '$'\r
+ jne petlja2a\r
+ pop si \r
+ pop dx\r
+ pop cx\r
+ pop bx\r
+ pop ax \r
+endm\r
+\r
+print_num macro num\r
+ inttostr num,strNZD\r
+ print_str strNZD\r
+endm\r
+;#macro-commands-end\r
+\r
+.code \r
+\r
+start:\r
+ mov ax,12\r
+ mov bx,8\r
+\r
+compare: \r
+ cmp ax,bx\r
+ je exit ;exit since they're equal\r
+ ja greater\r
+ sub bx,ax\r
+ jmp compare\r
+\r
+greater:\r
+ sub ax,bx\r
+ jmp compare\r
+\r
+exit:\r
+;exit out of the program\r
+ print_num ax\r
+; print out a result\r
+ end_execution\r
+\r
+.stack\r
+end start\r
diff --git a/samples-with-macros/rek-gcd-input.asm b/samples-with-macros/rek-gcd-input.asm
--- /dev/null
@@ -0,0 +1,222 @@
+.model small \r
+ASSUME DS:data\r
+;recursive version of GCD, input from terminal\r
+data segment\r
+ strNZD db " "\r
+ tempStr db " "\r
+ prompt db "num?$"\r
+ promptr db "RES $"\r
+ m dw 0\r
+ n dw 0\r
+data ends\r
+;#macro-commands-start\r
+; print a string on screen\r
+print_str macro s\r
+ push ax\r
+ push dx \r
+ mov dx, offset s\r
+ mov ah, 09\r
+ int 21h\r
+ pop dx\r
+ pop ax\r
+endm\r
+\r
+; new line\r
+print_new_line macro\r
+ push ax\r
+ push bx\r
+ push dx\r
+ mov ah,03\r
+ mov bh,0\r
+ int 10h\r
+ inc dh\r
+ mov dl,0\r
+ mov ah,02\r
+ int 10h\r
+ pop dx\r
+ pop bx\r
+ pop ax\r
+endm\r
+\r
+; write a single char\r
+print_char macro c\r
+ push ax \r
+ push dx\r
+ mov ah, 02\r
+ mov dl, c\r
+ int 21h\r
+ pop dx\r
+ pop ax\r
+endm\r
+\r
+; finish the execution\r
+end_execution macro\r
+ mov ax, 4c02h\r
+ int 21h\r
+endm \r
+\r
+; Konvertovanje broja u string\r
+inttostr macro num1 str1\r
+ push ax\r
+ push bx\r
+ push cx\r
+ push dx\r
+ push si\r
+ mov ax, num1\r
+ mov dl, '$'\r
+ push dx\r
+ mov si, 10\r
+petlja2:\r
+ mov dx, 0\r
+ div si\r
+ add dx, 48\r
+ push dx\r
+ cmp ax, 0\r
+ jne petlja2\r
+ \r
+ mov bx, offset str1\r
+petlja2a: \r
+ pop dx\r
+ mov [bx], dl\r
+ inc bx\r
+ cmp dl, '$'\r
+ jne petlja2a\r
+ pop si \r
+ pop dx\r
+ pop cx\r
+ pop bx\r
+ pop ax \r
+endm\r
+\r
+print_num macro num\r
+ inttostr num,strNZD\r
+ print_str strNZD\r
+endm \r
+\r
+read_num macro num\r
+ read_str tempStr,6\r
+ strtoint tempStr,num\r
+endm\r
+\r
+;read into a buffer, inc the special 0 and 1 bytes\r
+;fixes it into a $ terminated string\r
+read_str macro strbuff, strlen\r
+ LOCAL copystr\r
+ push ax\r
+ push bx\r
+ push cx\r
+ push dx\r
+ push si\r
+ mov bp, sp\r
+ mov dx, offset strbuff\r
+ mov bx, dx\r
+ mov ax, strlen\r
+ mov byte [bx] ,al\r
+ mov ah, 0Ah\r
+ int 21h\r
+ mov si, dx \r
+ mov cl, [si+1] \r
+ mov ch, 0\r
+copystr:\r
+ mov al, [si+2]\r
+ mov [si], al\r
+ inc si\r
+ loop copystr \r
+ mov [si], '$'\r
+ pop si \r
+ pop dx\r
+ pop cx\r
+ pop bx\r
+ pop ax\r
+endm\r
+\r
+;ascii to actual number\r
+strtoint macro inStr,outNum\r
+ LOCAL mainloop,end\r
+ push ax\r
+ push bx\r
+ push cx\r
+ push dx\r
+ push si\r
+ mov bp, sp\r
+ mov bx, offset inStr\r
+ mov ax, 0\r
+ mov cx, 0\r
+ mov si, 10\r
+mainloop:\r
+ mov cl, [bx]\r
+ cmp cl, '$'\r
+ je end\r
+ mul si\r
+ sub cx, 48\r
+ add ax, cx\r
+ inc bx \r
+ jmp mainloop\r
+end:\r
+ mov outNum, ax \r
+ pop si \r
+ pop dx\r
+ pop cx\r
+ pop bx\r
+ pop ax\r
+endm\r
+;#macro-commands-end\r
+\r
+.code\r
+\r
+start: \r
+ mov ax,@data\r
+ mov ds,ax\r
+ print_str prompt\r
+ read_num m \r
+ print_new_line\r
+ print_str prompt\r
+ read_num n\r
+ print_new_line\r
+\r
+ push n\r
+ push m\r
+ call gcd\r
+ pop n \r
+ print_str promptr\r
+ print_num n\r
+; print out a result\r
+ end_execution\r
+\r
+\r
+;volatile procedure, ruins ax,bx,cx\r
+gcd proc\r
+ ;;#extra-start\r
+ pop cx ;ret adress\r
+ ;;#extra-end\r
+ ;get params\r
+ pop ax\r
+ pop bx\r
+ ;;#extra-start\r
+ push cx ;ret for later \r
+ ;;#extra-end\r
+ cmp ax,bx\r
+ je endequal\r
+ ja greatera\r
+ ;ensure ax is greater\r
+ xchg ax,bx \r
+greatera:\r
+ sub ax,bx\r
+ push bx\r
+ push ax\r
+ call gcd\r
+ pop ax;result\r
+ \r
+endequal:\r
+ ;;#extra-start\r
+ pop cx\r
+ ;;#extra-end\r
+ push ax; result\r
+ ;;#extra-start\r
+ push cx;needed before ret\r
+ ;;#extra-end\r
+ ret\r
+gcd endp \r
+\r
+.stack\r
+end start\r
diff --git a/samples-with-macros/rek-gcd-predef.asm b/samples-with-macros/rek-gcd-predef.asm
--- /dev/null
@@ -0,0 +1,120 @@
+.model small \r
+;recursive version of GCD, predefined input\r
+data segment\r
+ strNZD db " "\r
+data ends\r
+;#macro-commands-start\r
+; print a string on screen\r
+print_str macro s\r
+ push ax\r
+ push dx \r
+ mov dx, offset s\r
+ mov ah, 09\r
+ int 21h\r
+ pop dx\r
+ pop ax\r
+endm\r
+\r
+\r
+; write a single char\r
+print_char macro c\r
+ push ax \r
+ push dx\r
+ mov ah, 02\r
+ mov dl, c\r
+ int 21h\r
+ pop dx\r
+ pop ax\r
+endm\r
+\r
+; finish the execution\r
+end_execution macro\r
+ mov ax, 4c02h\r
+ int 21h\r
+endm \r
+\r
+; Konvertovanje broja u string\r
+inttostr macro num1 str1\r
+ push ax\r
+ push bx\r
+ push cx\r
+ push dx\r
+ push si\r
+ mov ax, num1\r
+ mov dl, '$'\r
+ push dx\r
+ mov si, 10\r
+petlja2:\r
+ mov dx, 0\r
+ div si\r
+ add dx, 48\r
+ push dx\r
+ cmp ax, 0\r
+ jne petlja2\r
+ \r
+ mov bx, offset str1\r
+petlja2a: \r
+ pop dx\r
+ mov [bx], dl\r
+ inc bx\r
+ cmp dl, '$'\r
+ jne petlja2a\r
+ pop si \r
+ pop dx\r
+ pop cx\r
+ pop bx\r
+ pop ax \r
+endm\r
+\r
+print_num macro num\r
+ inttostr num,strNZD\r
+ print_str strNZD\r
+endm\r
+;#macro-commands-end\r
+\r
+.code\r
+ \r
+start:\r
+ push 8\r
+ push 12\r
+ call gcd\r
+ pop ax\r
+ print_num ax\r
+; print out a result\r
+ end_execution\r
+ \r
+;volatile procedure, ruins ax,bx,cx\r
+gcd proc\r
+;#extra-start\r
+ pop cx ;ret adress \r
+;#extra-end\r
+ ;get params\r
+ pop ax\r
+ pop bx\r
+;#extra-start\r
+ push cx ;ret for later \r
+;#extra-end\r
+ cmp ax,bx\r
+ je endequal\r
+ ja greatera\r
+ ;ensure ax is greater\r
+ xchg ax,bx \r
+greatera:\r
+ sub ax,bx\r
+ push bx\r
+ push ax\r
+ call gcd\r
+ pop ax;result\r
+ \r
+endequal:\r
+;#extra-start\r
+ pop cx\r
+;#extra-end\r
+ push ax; result\r
+;#extra-start\r
+ push cx;needed before ret\r
+;#extra-end\r
+ ret\r
+gcd endp\r
+.stack\r
+end start\r
diff --git a/samples-with-macros/sumn-stack-prompt.asm b/samples-with-macros/sumn-stack-prompt.asm
--- /dev/null
@@ -0,0 +1,197 @@
+.model small\r
+;#macro-commands-start\r
+; finish the execution\r
+end_execution macro\r
+ int 20h\r
+endm \r
+\r
+; print a string on screen\r
+print_str macro s\r
+ push ax\r
+ push dx \r
+ mov dx, offset s\r
+ mov ah, 09\r
+ int 21h\r
+ pop dx\r
+ pop ax\r
+endm\r
+ \r
+; write a single char\r
+print_char macro c\r
+ push ax \r
+ push dx\r
+ mov ah, 02\r
+ mov dl, c\r
+ int 21h\r
+ pop dx\r
+ pop ax\r
+endm\r
+\r
+; new line\r
+print_new_line macro\r
+ push ax\r
+ push bx\r
+ push dx\r
+ mov ah,03\r
+ mov bh,0\r
+ int 10h\r
+ inc dh\r
+ mov dl,0\r
+ mov ah,02\r
+ int 10h\r
+ pop dx\r
+ pop bx\r
+ pop ax\r
+endm\r
+\r
+\r
+; Konvertovanje broja u string\r
+inttostr macro num1 str1\r
+ push ax\r
+ push bx\r
+ push cx\r
+ push dx\r
+ push si\r
+ mov ax, num1\r
+ mov dl, '$'\r
+ push dx\r
+ mov si, 10\r
+petlja2:\r
+ mov dx, 0\r
+ div si\r
+ add dx, 48\r
+ push dx\r
+ cmp ax, 0\r
+ jne petlja2\r
+ \r
+ mov bx, offset str1\r
+petlja2a: \r
+ pop dx\r
+ mov [bx], dl\r
+ inc bx\r
+ cmp dl, '$'\r
+ jne petlja2a\r
+ pop si \r
+ pop dx\r
+ pop cx\r
+ pop bx\r
+ pop ax \r
+endm\r
+\r
+print_num macro num\r
+ inttostr num,tempStr\r
+ print_str tempStr\r
+endm\r
+\r
+read_num macro num\r
+ read_str tempStr,6\r
+ ;push offset tempStr\r
+ ;push offset num\r
+ strtoint tempStr,num\r
+endm\r
+\r
+;read into a buffer, inc the special 0 and 1 bytes\r
+;fixes it into a $ terminated string\r
+read_str macro strbuff, strlen\r
+ LOCAL copystr\r
+ push ax\r
+ push bx\r
+ push cx\r
+ push dx\r
+ push si\r
+ mov bp, sp\r
+ mov dx, offset strbuff\r
+ mov bx, dx\r
+ mov ax, strlen\r
+ mov byte [bx] ,al\r
+ mov ah, 0Ah\r
+ int 21h\r
+ mov si, dx \r
+ mov cl, [si+1] \r
+ mov ch, 0\r
+copystr:\r
+ mov al, [si+2]\r
+ mov [si], al\r
+ inc si\r
+ loop copystr \r
+ mov [si], '$'\r
+ pop si \r
+ pop dx\r
+ pop cx\r
+ pop bx\r
+ pop ax\r
+endm\r
+\r
+;ascii to actual number\r
+strtoint macro inStr,outNum\r
+ LOCAL mainloop,end\r
+ push ax\r
+ push bx\r
+ push cx\r
+ push dx\r
+ push si\r
+ mov bp, sp\r
+ mov bx, offset inStr\r
+ mov ax, 0\r
+ mov cx, 0\r
+ mov si, 10\r
+mainloop:\r
+ mov cl, [bx]\r
+ cmp cl, '$'\r
+ je end\r
+ mul si\r
+ sub cx, 48\r
+ add ax, cx\r
+ inc bx \r
+ jmp mainloop\r
+end:\r
+ mov outNum, ax \r
+ pop si \r
+ pop dx\r
+ pop cx\r
+ pop bx\r
+ pop ax\r
+endm\r
+;#macro-commands-end\r
+\r
+.code\r
+;read_num, print_num, etc are macros\r
+\r
+start: \r
+ mov ax, data\r
+ mov ds, ax \r
+ print_str prompt\r
+ read_num n\r
+ mov cx, n\r
+l1: \r
+ print_str prompt\r
+ read_num num\r
+ push num\r
+ loop l1\r
+ ; now sum up the top n from the stack\r
+ mov cx, n\r
+ mov ax, 0\r
+ mov dx, 0\r
+theloop:\r
+ pop ax ; get next from stack\r
+ add dx, ax ; array sum is in dx\r
+ loop theloop\r
+ ; result \r
+ print_new_line\r
+ print_str resStr\r
+ print_num dx\r
+end1:\r
+ nop\r
+ end_execution\r
+\r
+\r
+.data\r
+ num dw 12\r
+ n dw 3\r
+ rez dw 0 \r
+ tempStr db " "\r
+ prompt db "number? $"\r
+ resStr db "result $"\r
+\r
+.stack\r
+end start\r
diff --git a/samples/array-sum-input.asm b/samples/array-sum-input.asm
--- /dev/null
@@ -0,0 +1,53 @@
+.model small\r
+;make a sum of an array - version with loading values\r
+;predefined array size\r
+\r
+;#macros-removed-from-listing
+\r
+.code\r
+start:\r
+ mov dx, @data\r
+ mov ds, dx \r
+ print_str prompt\r
+ read_num n\r
+ mov ax, 0\r
+ mov cx, n\r
+ cmp maxn, cx\r
+ jae normal\r
+ print_str errorN\r
+ end_execution\r
+normal: \r
+loadloop:\r
+ print_str prompt\r
+ read_num t\r
+ mov ax,t\r
+ mov bx,n\r
+ sub bx,cx\r
+ mov niz[bx],al\r
+ loop loadloop\r
+ print_new_line\r
+ ; now sum up\r
+ mov cx, n\r
+ xor ax,ax\r
+mainloop: \r
+ mov bx, cx\r
+ add al, niz[bx-1] ; get array memeber, byte\r
+ ; store sum in al\r
+ loop mainloop ; end calc if done\r
+ print_num ax\r
+ end_execution\r
+\r
+data segment\r
+n dw 7\r
+t dw 0\r
+maxn dw 20\r
+niz db 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0 \r
+tempStr db " "\r
+prompt db "Number?$"\r
+errorN db "Number too large!$"\r
+ends\r
+end start\r
+\r
+\r
+\r
+\r
diff --git a/samples/array-sum-predef.asm b/samples/array-sum-predef.asm
--- /dev/null
@@ -0,0 +1,27 @@
+.model small\r
+;make a sum of an array - version with predefined everything\r
+\r
+;#macros-removed-from-listing
+\r
+.code\r
+start:\r
+ mov dx, @data\r
+ mov ds, dx \r
+ mov cx, n\r
+ mov ax, 0\r
+ mov dx, 0\r
+mainloop: \r
+ mov bx, cx\r
+ add al, niz[bx-1] ; get array memeber, byte\r
+ ; store sum in al\r
+ loop mainloop ; end calc if done\r
+ print_num ax\r
+ end_execution\r
+ \r
+data segment\r
+n dw 7\r
+niz db 1,2,3,4,5,6,7,0 \r
+tempStr db " "\r
+\r
+ends\r
+end start\r
diff --git a/samples/fakt.asm b/samples/fakt.asm
--- /dev/null
+++ b/samples/fakt.asm
@@ -0,0 +1,57 @@
+; Evolucija Softvera\r
+; Racunanje faktoriela pomocu sateka i sabiranja\r
+\r
+.286\r
+.model small\r
+\r
+sseg segment stack\r
+ db 256 dup (?)\r
+sseg ends\r
+\r
+.data\r
+n dw 5 ; racunamo faktoriel od 7\r
+niz db 5,4,3,2,1\r
+\r
+.code\r
+ mov dx, @data\r
+ mov ds, dx\r
+ ; Direktno indeksno - pomocu labela[DI] i labela[SI]\r
+ ;rezultat u dx\r
+ mov ax, 0\r
+ mov bx, 0\r
+ mov cx,0\r
+ mov dx,0\r
+ mov dl, niz[bx] ;ubacuje najveci clan n koji ce biti sabran n-1 put\r
+ inc bx ;krece od drugog clana \r
+ \r
+petlja:\r
+ mov cl, niz[bx] ; citaj clan niza\r
+ cmp cx,1 ; da li je ax=1?\r
+ je kraj ; ako jeste, idi na kraj\r
+ \r
+ubaci: ;ubacuje na stek prethodni rezultat n-1 put\r
+ cmp cx,1\r
+ je pom\r
+ push dx\r
+ dec cx\r
+ jmp ubaci\r
+ \r
+pom: \r
+ mov cl, niz[bx] ;uzima vrednost da koliko puta skida sa steka\r
+ \r
+mnozenje:\r
+ cmp cx,1\r
+ je sledeci\r
+ pop ax\r
+ add dx,ax\r
+ dec cx\r
+ jmp mnozenje\r
+ \r
+sledeci: \r
+ inc bx\r
+ jmp petlja\r
+\r
+kraj:\r
+ print_num dx ;ispisi rezultat na kraju\r
+ nop\r
+ end\r
diff --git a/samples/gcd-input.asm b/samples/gcd-input.asm
--- /dev/null
+++ b/samples/gcd-input.asm
@@ -0,0 +1,48 @@
+.model small\r
+;greatest common divisor, with input from terminal\r
+data segment\r
+ tempStr db " "\r
+ prompt db "num?$"\r
+ promptr db "RES $"\r
+ m dw 0\r
+ n dw 0\r
+\r
+data ends\r
+;#macros-removed-from-listing
+\r
+.code \r
+\r
+start: \r
+ mov ax,@data\r
+ mov ds,ax\r
+ print_str prompt\r
+ read_num m \r
+ print_new_line\r
+ print_str prompt\r
+ read_num n\r
+ print_new_line\r
+\r
+ mov ax,n\r
+ mov bx,m\r
+\r
+compare: \r
+ cmp ax,bx\r
+ je exit ;exit since they're equal\r
+ ja greater\r
+ sub bx,ax\r
+ jmp compare\r
+\r
+greater:\r
+ sub ax,bx\r
+ jmp compare\r
+\r
+exit:\r
+;exit out of the program\r
+ mov n,ax\r
+ print_str promptr\r
+ print_num n\r
+; print out a result\r
+ end_execution\r
+\r
+.stack\r
+end start\r
diff --git a/samples/gcd-predef.asm b/samples/gcd-predef.asm
--- /dev/null
+++ b/samples/gcd-predef.asm
@@ -0,0 +1,31 @@
+.model small\r
+data segment\r
+ strNZD db " "\r
+data ends\r
+;#macros-removed-from-listing
+\r
+.code \r
+\r
+start:\r
+ mov ax,12\r
+ mov bx,8\r
+\r
+compare: \r
+ cmp ax,bx\r
+ je exit ;exit since they're equal\r
+ ja greater\r
+ sub bx,ax\r
+ jmp compare\r
+\r
+greater:\r
+ sub ax,bx\r
+ jmp compare\r
+\r
+exit:\r
+;exit out of the program\r
+ print_num ax\r
+; print out a result\r
+ end_execution\r
+\r
+.stack\r
+end start\r
diff --git a/samples/procgcd.asm b/samples/procgcd.asm
--- /dev/null
+++ b/samples/procgcd.asm
@@ -0,0 +1,36 @@
+.model small\r
+.code \r
+ push br1\r
+ push br2\r
+ call gcd\r
+ pop rez\r
+end1:\r
+ print_num rez\r
+ nop\r
+\r
+gcd proc\r
+ pop ax ;mov ax,[bp+8]\r
+ pop bx ;mov bx,[bp+6]\r
+compare: \r
+ cmp ax,bx\r
+ je endp\r
+ cmp ax,bx\r
+ ja greater\r
+ sub bx,ax\r
+ jmp compare\r
+\r
+greater:\r
+ sub ax,bx\r
+ jmp compare\r
+\r
+endp:\r
+ push ax ;result\r
+ ret\r
+gcd endp\r
+\r
+.data\r
+ br1 dw 12\r
+ br2 dw 8\r
+ rez dw 0 \r
+.stack\r
+end\r
diff --git a/samples/rek-gcd-input.asm b/samples/rek-gcd-input.asm
--- /dev/null
@@ -0,0 +1,59 @@
+.model small \r
+ASSUME DS:data\r
+;recursive version of GCD, input from terminal\r
+data segment\r
+ strNZD db " "\r
+ tempStr db " "\r
+ prompt db "num?$"\r
+ promptr db "RES $"\r
+ m dw 0\r
+ n dw 0\r
+data ends\r
+;#macros-removed-from-listing
+\r
+.code\r
+\r
+start: \r
+ mov ax,@data\r
+ mov ds,ax\r
+ print_str prompt\r
+ read_num m \r
+ print_new_line\r
+ print_str prompt\r
+ read_num n\r
+ print_new_line\r
+\r
+ push n\r
+ push m\r
+ call gcd\r
+ pop n \r
+ print_str promptr\r
+ print_num n\r
+; print out a result\r
+ end_execution\r
+\r
+\r
+;volatile procedure, ruins ax,bx,cx\r
+gcd proc\r
+ ;get params\r
+ pop ax\r
+ pop bx\r
+ cmp ax,bx\r
+ je endequal\r
+ ja greatera\r
+ ;ensure ax is greater\r
+ xchg ax,bx \r
+greatera:\r
+ sub ax,bx\r
+ push bx\r
+ push ax\r
+ call gcd\r
+ pop ax;result\r
+ \r
+endequal:\r
+ push ax; result\r
+ ret\r
+gcd endp \r
+\r
+.stack\r
+end start\r
diff --git a/samples/rek-gcd-predef.asm b/samples/rek-gcd-predef.asm
--- /dev/null
@@ -0,0 +1,41 @@
+.model small \r
+;recursive version of GCD, predefined input\r
+data segment\r
+ strNZD db " "\r
+data ends\r
+;#macros-removed-from-listing
+\r
+.code\r
+ \r
+start:\r
+ push 8\r
+ push 12\r
+ call gcd\r
+ pop ax\r
+ print_num ax\r
+; print out a result\r
+ end_execution\r
+ \r
+;volatile procedure, ruins ax,bx,cx\r
+gcd proc\r
+ ;get params\r
+ pop ax\r
+ pop bx\r
+ cmp ax,bx\r
+ je endequal\r
+ ja greatera\r
+ ;ensure ax is greater\r
+ xchg ax,bx \r
+greatera:\r
+ sub ax,bx\r
+ push bx\r
+ push ax\r
+ call gcd\r
+ pop ax;result\r
+ \r
+endequal:\r
+ push ax; result\r
+ ret\r
+gcd endp\r
+.stack\r
+end start\r
diff --git a/samples/sumn-stack-prompt.asm b/samples/sumn-stack-prompt.asm
--- /dev/null
@@ -0,0 +1,44 @@
+.model small\r
+;#macros-removed-from-listing
+\r
+.code\r
+;read_num, print_num, etc are macros\r
+\r
+start: \r
+ mov ax, data\r
+ mov ds, ax \r
+ print_str prompt\r
+ read_num n\r
+ mov cx, n\r
+l1: \r
+ print_str prompt\r
+ read_num num\r
+ push num\r
+ loop l1\r
+ ; now sum up the top n from the stack\r
+ mov cx, n\r
+ mov ax, 0\r
+ mov dx, 0\r
+theloop:\r
+ pop ax ; get next from stack\r
+ add dx, ax ; array sum is in dx\r
+ loop theloop\r
+ ; result \r
+ print_new_line\r
+ print_str resStr\r
+ print_num dx\r
+end1:\r
+ nop\r
+ end_execution\r
+\r
+\r
+.data\r
+ num dw 12\r
+ n dw 3\r
+ rez dw 0 \r
+ tempStr db " "\r
+ prompt db "number? $"\r
+ resStr db "result $"\r
+\r
+.stack\r
+end start\r
diff --git a/samples/sumn3.asm b/samples/sumn3.asm
--- /dev/null
+++ b/samples/sumn3.asm
@@ -0,0 +1,36 @@
+.model small\r
+.code\r
+;read_num, print_num are macros\r
+ read_num n\r
+ mov cx, n\r
+l1:\r
+ read_num num\r
+ push num\r
+ loop l1\r
+ push n\r
+ call sumn\r
+ pop rez\r
+ print_num rez\r
+end1:\r
+ nop\r
+\r
+sumn proc\r
+;n is on top of the stack\r
+;sum the next n top elements of the stack\r
+ pop cx \r
+ mov ax, 0\r
+ mov dx, 0\r
+theloop:\r
+ pop ax ; get next from stack\r
+ add dx, ax ; array sum is in dx\r
+ loop theloop\r
+ push dx ; result\r
+ ret\r
+sumn endp\r
+\r
+.data\r
+ num dw 12\r
+ n dw 3\r
+ rez dw 0 \r
+.stack\r
+end\r
diff --git a/src-wsl/metrics_csv.wsl b/src-wsl/metrics_csv.wsl
--- /dev/null
+++ b/src-wsl/metrics_csv.wsl
@@ -0,0 +1,195 @@
+C:"Doni Pracner (c) 2015";
+C:"
+This program is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 3 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU General Public License for more
+details.
+
+You should have received a copy of the GNU General Public
+License along with this program. If not, see
+<http://www.gnu.org/licenses/>.
+==========================================================";
+
+C:"This program generates metrics for WSL programs,
+including options for comparing two programs (mainly ment to
+compare different versions) and output differences as direct
+numbers and percentages in a CSV type of format.
+
+One of the goals was to enable this to be used both in the
+command line for quick checks but also to be used for
+automation and creation of CSV files for collections of
+programs.";
+
+C:"usage {option} {filename}";
+
+C:"Options";
+C:" -h or --help - help screen";
+C:" -H or --header - print header for metrics";
+C:" -c 'file1' 'file2' - compare two files and print the metrics";
+C:" -HC print header for comparison";
+C:" -o 'file' - set output for the print";
+C:" -s 'separator' - set the separator in outputs (default comma)";
+C:" otherwise print the metrics of the given file(s)";
+
+C:"options are processed in sequence, so you can have
+for instance multiple outputs during the execution and
+run it for different programs";
+
+C:"examples;
+
+'filename' 'file2' 'file3'
+ - just output the metrics all files on the screen,
+ each in it's own row
+
+-c 'f1' 'f2'
+ - compare two files and output the differences on the
+ screen
+
+-o res.tmp -HC -c 'f1' 'f1a' -c 'f2' 'f2a'
+ - output a header row and two rows comparing the given
+ files in the specified file
+";
+
+Field_Separator := ",";
+
+MW_PROC @Get_New_Name(VAR str) ==
+ IF @Ends_With?(str, ".wsl") THEN
+ str := SUBSTR(str, 0, SLENGTH(str)-4)
+ FI;
+ str := str ++ ".met"
+END;
+
+MW_PROC @Process_File(filename VAR metricslist) ==
+ metricslist := < >;
+ IF @File_Exists?(filename) THEN
+ @New_Program(@Parse_File(filename, T_Statements));
+
+ C:"add them in reverse to the start of the list";
+ metricslist := < @Struct_Metric(@Program) > ++ metricslist ;
+ metricslist := < @Total_Size(@Program) > ++ metricslist ;
+ metricslist := < @CFDF_Metric(@Program) > ++ metricslist ;
+ metricslist := < @Gen_Type_Count(T_Expression,@Program) > ++ metricslist ;
+ metricslist := < @Stat_Count(@Program) > ++ metricslist ;
+ metricslist := < @Essential(@Program) > ++ metricslist ;
+ metricslist := < @McCabe(@Program) > ++ metricslist
+ ELSE
+ PRINT("ERROR: File ",filename," not found");
+ FI
+END;
+
+MW_PROC @Write_Metrics(metrics VAR) ==
+ FOR met IN metrics DO
+ @WS(Field_Separator);
+ @WN(met)
+ OD
+END;
+
+MW_PROC @Write_Metrics_List(prefix VAR) ==
+ @WS(prefix);@WS("McCabe Cyclo");@WS(Field_Separator);
+ @WS(prefix);@WS("McCabe Essential");@WS(Field_Separator);
+ @WS(prefix);@WS("Statements");@WS(Field_Separator);
+ @WS(prefix);@WS("Expressions");@WS(Field_Separator);
+ @WS(prefix);@WS("CFDF");@WS(Field_Separator);
+ @WS(prefix);@WS("Size");@WS(Field_Separator);
+ @WS(prefix);@WS("Structure")
+END;
+
+MW_PROC @Metrics_Main() ==
+VAR< prog := < >,
+ filename:="", filename2 := "",
+ metrics := < >, met2 := < >,
+ opened := 0,
+ Argv := ARGV
+>:
+C:"First one is the script name that is being executed";
+Argv := TAIL(Argv);
+
+IF Argv = < > THEN
+ PRINT("no arguments passed; supply a filename to make metrics for ");
+ELSE
+ WHILE Argv <> < > DO
+ POP(filename,Argv);
+ IF filename = "-h" OR filename = "--help" THEN
+ PRINT("HELP - for now in the comments at the start of the script");
+ PRINT("options: --header or -H | -c | -HC | -o | -s");
+ SKIP
+ ELSIF filename = "-H" OR filename = "--header" THEN
+ @WS("filename");@WS(Field_Separator);
+ @Write_Metrics_List("");
+ @WL("");
+ ELSIF filename = "-HC" THEN
+ C:"Header for comparison";
+ @WS("filename");@WS(Field_Separator);
+ @Write_Metrics_List("P1-");@WS(Field_Separator);
+ @Write_Metrics_List("P2-");@WS(Field_Separator);
+ @Write_Metrics_List("DIFF-");@WS(Field_Separator);
+ @Write_Metrics_List("%-");
+ @WL("");
+ ELSIF filename = "-o" THEN
+ C:"set output";
+ IF Argv = < > THEN
+ PRINT("argument needed after -o")
+ ELSE
+ POP(filename, Argv);
+ opened := opened + 1;
+ @Write_To(filename)
+ FI
+ ELSIF filename = "-s" THEN
+ C:"set separator";
+ IF Argv = < > THEN
+ PRINT("argument needed after -s")
+ ELSE
+ POP(Field_Separator, Argv);
+ FI
+ ELSIF filename = "-c" THEN
+ C:"compare two files and dump the comparison";
+ IF LENGTH(Argv) < 2 THEN
+ PRINT("two arguments needed after -c")
+ ELSE
+ POP(filename, Argv);
+
+ @Process_File(filename VAR metrics);
+ @WS(filename);
+ @Write_Metrics(metrics);
+
+ POP(filename2,Argv);
+ @Process_File(filename2 VAR met2);
+ @Write_Metrics(met2);
+
+ C:"calculate the differences";
+ FOR i := 1 TO LENGTH(metrics) STEP 1 DO
+ met2[i] := metrics[i] - met2[i];
+ IF metrics[i] <> 0 THEN
+ metrics[i] := met2[i] * 100 DIV metrics[i]
+ FI
+ OD;
+ @Write_Metrics(met2);
+ @Write_Metrics(metrics);
+
+ @WL("");
+ FI;
+ SKIP
+ ELSE
+ @Process_File(filename VAR metrics);
+ @WS(filename);
+ @Write_Metrics(metrics);
+ @WL("");
+ SKIP
+ FI
+ OD;
+ C:"be nice and close all the opened writes";
+ FOR count := 1 TO opened STEP 1 DO
+ @End_Write
+ OD
+FI
+ENDVAR
+END;
+
+@Metrics_Main()
diff --git a/src-wsl/transf-min.wsl b/src-wsl/transf-min.wsl
--- /dev/null
+++ b/src-wsl/transf-min.wsl
@@ -0,0 +1,154 @@
+C:"
+Copyright (C) 2012,2015 Doni Pracner
+http://perun.dmi.rs/pracner
+
+This program is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 3 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU General Public License for more
+details.
+
+You should have received a copy of the GNU General Public
+License along with this program. If not, see
+<http://www.gnu.org/licenses/>.
+==========================================================";
+
+C:"Automatic transformation tool for simplification of WSL";
+C:"code automaticaly translated from assembly using asm2wsl.";
+
+C:"a very simple version, ment to be fast and relatively
+efficient. It is aimed at action-system programs and should
+remove them from the program, while doing other
+simlifications in the process.";
+
+C:"set the following so that Action Systems are not
+automaticaly treated as regular";
+C:"Not neccessary with recent versions of FermaT";
+Assume_A_S_Regular := 0;
+
+C:"Main procedure to transform the loaded program";
+MW_PROC @Process_Prog() ==
+
+ @Trans(TR_Constant_Propagation, "");
+
+ C:"Try to remove the Action systems";
+ FOREACH Statement DO
+ IF @ST(@I) = T_A_S THEN
+ IF @Trans?(TR_Simplify_Action_System) THEN
+ @Trans(TR_Simplify_Action_System, "")
+ FI;
+ IF @Trans?(TR_Collapse_Action_System) THEN
+ @Trans(TR_Collapse_Action_System, "");
+ FI;
+ ELSIF @Trans?(TR_Remove_All_Redundant_Vars) THEN
+ @Trans(TR_Remove_All_Redundant_Vars, "");
+ ELSIF @ST(@I) = T_Skip THEN
+ @Delete
+ FI
+ OD;
+
+ C:"remove all the comments ";
+ FOREACH Statement DO
+ IF @ST(@I) = T_Comment THEN
+ @Delete
+ FI
+ OD;
+
+ FOREACH Statement DO
+ IF @Trans?(TR_Simplify_Item) THEN
+ @Trans(TR_Simplify_Item,"")
+ FI
+ OD;
+
+ C:"Convert DO loops into WHILE loops";
+ FOREACH Statement DO
+ IF @Trans?(TR_Floop_To_While) THEN
+ @Trans(TR_Floop_To_While, "");
+ FI
+ OD;
+ C:"Go back to the start, and remove redundant";
+ @Goto(< >);
+ @Trans(TR_Delete_All_Redundant, "");
+ SKIP
+END;
+
+MW_PROC @Get_New_Name(VAR str) ==
+ IF @Ends_With?(str, ".wsl") THEN
+ str := SUBSTR(str, 0, SLENGTH(str)-4)
+ FI;
+ str := str ++ "_t.wsl"
+END;
+
+MW_PROC @Prog_Stat_Comp(Pro, After VAR)==
+ VAR < ma := 0, mb :=1 > :
+ ma := @McCabe(Pro);
+ mb := @McCabe(After);
+ PRINT ("McCabe ", ma, " ", mb, " ",(mb-ma));
+ ma := @Stat_Count(Pro);
+ mb := @Stat_Count(After);
+ PRINT ("Statem ", ma, " ",mb, " ",(mb-ma));
+ ma := @CFDF_Metric(Pro);
+ mb := @CFDF_Metric(After);
+ PRINT ("CF/DF ", ma," ", mb," ", (mb-ma));
+ ma := @Total_Size(Pro);
+ mb := @Total_Size(After);
+ PRINT ("Size ", ma," ", mb, " ",(mb-ma));
+ ma := @Struct_Metric(Pro);
+ mb := @Struct_Metric(After);
+ PRINT ("Struct ", ma, " ",mb, " ",(mb-ma));
+ SKIP
+ ENDVAR
+END;
+
+MW_PROC @Process_File(filename) ==
+ IF @File_Exists?(filename) THEN
+ @New_Program(@Parse_File(filename, T_Statements));
+ PRINT("Processing: ", filename);
+ prog := @Program;
+ @Process_Prog();
+ @Get_New_Name(VAR filename);
+ @PP_Item(@Program, 80, filename);
+ PRINT(filename);
+ @Prog_Stat_Comp(prog, @Program);
+ ELSE
+ PRINT("ERROR: File ",filename," not found");
+ FI
+END;
+
+VAR< prog := < >, inifilename := "transf.ini",
+ filename:="", file := "", inifile:= "",
+ Argv := ARGV
+>:
+C:"First one is the script name that is being executed";
+Argv := TAIL(Argv);
+
+IF Argv = < > THEN
+ PRINT("no arguments passed; using ",inifilename);
+ IF @File_Exists?(inifilename) THEN
+ inifile := @Open_Input_File(inifilename);
+ filename := @Read_Line(inifile);
+ C:"check if the loaded is an EOF";
+ WHILE NOT @EOF?(filename) DO
+ @Process_File(filename);
+ filename := @Read_Line(inifile)
+ OD;
+ @Close_Input_Port(inifile);
+ ELSE
+ PRINT("ini file (",inifilename,") not found.",
+ " it should contain a list of filenames to be converted");
+ PRINT("you can input a filename now:");
+ filename := @Read_Line(Standard_Input_Port);
+ @Process_File(filename);
+ FI
+ELSE
+ FOR arg IN Argv DO
+ @Process_File(arg);
+ OD
+FI
+ENDVAR
diff --git a/src/asm2wsl.java b/src/asm2wsl.java
--- /dev/null
+++ b/src/asm2wsl.java
@@ -0,0 +1,746 @@
+\r
+/* \r
+Copyright 2012,2018 Doni Pracner\r
+\r
+This program is free software: you can redistribute it\r
+and/or modify it under the terms of the GNU General Public\r
+License as published by the Free Software Foundation, either\r
+version 3 of the License, or (at your option) any later\r
+version.\r
+\r
+This program is distributed in the hope that it will be\r
+useful, but WITHOUT ANY WARRANTY; without even the implied\r
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR\r
+PURPOSE. See the GNU General Public License for more\r
+details.\r
+\r
+You should have received a copy of the GNU General Public\r
+License along with this program. If not, see\r
+<http://www.gnu.org/licenses/>.\r
+\r
+*/\r
+import java.io.*;\r
+import java.util.*;\r
+\r
+/**\r
+ * This program converts files from assembly x86 to WSL language which is a part\r
+ * of the FermaT Transformation system.<br />\r
+ * Currently it works only on a very limited subset of x86, and has a number of\r
+ * predefined macro names it uses for translation. It works with 16 bit\r
+ * registers (ax,bx, etc) and presumes that the rest of the variables are 8bit\r
+ * if not applied to a 16bit reg. Check the documentation for more details.\r
+ *\r
+ * @author Doni Pracner, http://perun.dmi.rs/pracner http://quemaster.com\r
+ */\r
+public class asm2wsl {\r
+\r
+ private static final String PROCEDURE_INTERNAL_SYS = "procedure_internal_sys";\r
+\r
+ /** translation processing switch */\r
+ public boolean originalInComments = false, translateComments = true,\r
+ addMemoryDump = false, translateToPopPush = true;\r
+\r
+ int mode = MODE_0, nUnknownC = 0, nUnknownD = 0, nKnownC = 0;\r
+\r
+ boolean labelfound = false;\r
+\r
+ public static final String versionN = "0.81";\r
+\r
+ // regular comments from the original file\r
+ // OC when original code is inserted in the file, next to the translations\r
+ // SPEC special messages from the translator\r
+ // ERR error messages from the translator\r
+ public static final char C_REG = ' ', C_OC = '#', C_SPEC = '&', C_ERR = '!';\r
+\r
+ public static final int MODE_0 = 0, MODE_CODE = 1, MODE_DATA = 2,\r
+ MODE_STACK = 3, N_MODES = 4;\r
+\r
+ public static final String CODE_SEG_START = "SKIP;\n ACTIONS A_S_start:\n A_S_start ==",\r
+ CODE_SEG_END = "CALL Z;\nSKIP END\nENDACTIONS;\n",\r
+ DATA_SEG_START = "VAR< ", DATA_SEG_END = " \tskipvar := 0 \n>:\n",\r
+ fixl = "\n%x := (%x DIV 256) * 256 + t_e_m_p;",\r
+ fixh = "\n%x := (%x MOD 256) + t_e_m_p * 256;";\r
+\r
+ public String getStandardStart() {\r
+ String ret = "C:\" This file automatically converted from assembler\";\n"\r
+ + "C:\" with asm2wsl v " + versionN + "\";\n";\r
+ ret += "VAR < ax := 0, bx := 0, cx := 0, dx := 0,\n"\r
+ + " si := 0, di := 0, bp := 0, sp := 0, \n"\r
+ + " ss := 0, ds := 0, cs := 0, es := 0,\n"\r
+ + " flag_o := 0, flag_d := 0, flag_i := 0, flag_t := 0,\n"\r
+ + " flag_z := 0, flag_s := 0, flag_p := 0, flag_a := 0,\n"\r
+ + " flag_c := 0, overflow := 256, stack := < >, t_e_m_p := 0 > :\n";\r
+ if (addMemoryDump)\r
+ ret += "BEGIN\n";\r
+ return ret;\r
+ }\r
+\r
+ public String getStandardEnd() {\r
+ String ret = "ENDVAR;\n";\r
+ if (addMemoryDump) {\r
+ ret += "C:\" end original program. testing features following\";\n"\r
+ + "WHERE\n" + "PROC memdump(VAR) ==\n"\r
+ + " PRINT(\"'memory' dump: \");\n"\r
+ + " PRINT(\"ax \",ax,\" bx \",bx,\" cx \",cx,\" dx \",dx);\n"\r
+ + " PRINT(\"flags:\");\n" + " PRINT(\"ODITSZAPC\");\n"\r
+ + " PRINT(flag_o,flag_d,flag_i,flag_t,flag_s,flag_z,flag_a,flag_p,flag_c)\n"\r
+ + "END\n" + "END\n";\r
+ }\r
+ ret += "\nENDVAR";\r
+ return ret;\r
+ }\r
+\r
+ /**\r
+ * When the param works with array addressing, this should reformat it so\r
+ * that it works as intended. An important thing to remember is that there\r
+ * is a[0] element in WSL, all arrays start with a[1].\r
+ */\r
+ public String arrayFix(String str) {\r
+ String param = str.substring(str.indexOf('[') + 1, str.indexOf(']'));\r
+ return str.replace(param + "]", formatParam(param) + "+1]");\r
+ }\r
+\r
+ /**\r
+ * Transforms an asembler source parameter as need so that it can be used in\r
+ * WSL. Among other things it converts Hex numbers to decimal, fixes array\r
+ * access indexes and the high/low parts of registers.\r
+ */\r
+ public String formatParam(String str) {\r
+ str = str.toLowerCase();\r
+ if (str.contains("["))\r
+ str = arrayFix(str);\r
+ try {\r
+ if (str.matches("[0-9][0-9a-f]*h"))\r
+ return "" + Integer.parseInt(str.substring(0, str.length() - 1),\r
+ 16);\r
+ } catch (Exception e) {\r
+ System.err.println("error in hex param procesing");\r
+ e.printStackTrace();\r
+ }\r
+ if (str.compareTo("al") == 0)\r
+ return "(ax MOD 256)";\r
+ else if (str.compareTo("ah") == 0)\r
+ return "(ax DIV 256)";\r
+ else if (str.compareTo("bl") == 0)\r
+ return "(bx MOD 256)";\r
+ else if (str.compareTo("bh") == 0)\r
+ return "(bx DIV 256)";\r
+ else if (str.compareTo("cl") == 0)\r
+ return "(cx MOD 256)";\r
+ else if (str.compareTo("ch") == 0)\r
+ return "(cx DIV 256)";\r
+ else if (str.compareTo("dl") == 0)\r
+ return "(dx MOD 256)";\r
+ else if (str.compareTo("dh") == 0)\r
+ return "(dx DIV 256)";\r
+ else\r
+ // for undefined variables\r
+ if (str.compareTo("(?)") == 0)\r
+ return "\" \"";\r
+ else\r
+\r
+ return str;\r
+ }\r
+\r
+ /**\r
+ * Transforms an asembler destination parameter as need so that it can be\r
+ * used in WSL. Among other things it fixes array access indexes and the\r
+ * high/low parts of registers.\r
+ */\r
+ public String formatDst(String str) {\r
+ if (str.contains("["))\r
+ str = arrayFix(str);\r
+ str = str.toLowerCase();\r
+ if (str.length() == 2 && str.charAt(0) >= 'a' && str.charAt(0) <= 'd'\r
+ && (str.charAt(1) == 'l' || str.charAt(1) == 'h'))\r
+ return "t_e_m_p";\r
+ else\r
+ return str;\r
+ }\r
+\r
+ /**\r
+ * Used for fixing low/high register access. The given param should be the\r
+ * dst operand of an assembler command.\r
+ */\r
+ public String getXRegisterFix(String str) {\r
+ str = str.toLowerCase();\r
+ if (str.length() == 2 && str.charAt(0) >= 'a' && str.charAt(0) <= 'd') {\r
+ char c = str.charAt(0);\r
+ if (str.charAt(1) == 'l')\r
+ return fixl.replace('%', c);\r
+ if (str.charAt(1) == 'h')\r
+ return fixh.replace('%', c);\r
+ }\r
+ return "";\r
+ }\r
+\r
+ /**\r
+ * Creates a WSL comment with care to quote chars.\r
+ */\r
+ public static String createComment(String str) {\r
+ return createComment(str, C_REG);\r
+ }\r
+\r
+ /**\r
+ * Creates a WSL comment with care to quote chars, of the given type. Types\r
+ * are given as char constants. They can be default comments, comments that\r
+ * contain the original code in them, or additional comments regarding the\r
+ * translation process.\r
+ */\r
+ public static String createComment(String str, char type) {\r
+ return "C:\"" + type + str.replace("\"", "''") + "\";";\r
+ }\r
+\r
+ /**\r
+ * Creates a wsl statement that modifies the overflow limit based on the\r
+ * input string that should be the parameter of a command.\r
+ */\r
+ public String getOverflow(String str) {\r
+ int over = 256;\r
+ str = str.toLowerCase();\r
+ if (str.length() == 2) {\r
+ if ((str.charAt(1) == 'x' && str.charAt(0) >= 'a'\r
+ && str.charAt(0) <= 'd')\r
+ || (str.compareTo("si") == 0 || str.compareTo("bp") == 0))\r
+ over = 65536;\r
+ }\r
+ return "overflow := " + over + "; ";\r
+ }\r
+\r
+ private void debugPrint(ArrayList<String> com) {\r
+ System.out.println();\r
+ for (int i = 0; i < com.size(); i++) {\r
+ System.out.print(com.get(i));\r
+ System.out.print("||");\r
+ }\r
+ }\r
+\r
+ private boolean inMacro = false;\r
+\r
+ // internal state, if a procedure body is being translated currently\r
+ private boolean inProcedure = false;\r
+\r
+ // the name of the procedure currently translated, if there is one\r
+ private String currentProcName = "";\r
+\r
+ /**\r
+ * Takes a single assembler line and returns the translated WSL line(s). It\r
+ * also changes the translator modes (data, code etc).\r
+ */\r
+ public String processLine(String str) {\r
+ /* Most of the logic is here, some parts could be split off */\r
+ if (str.length() == 0)\r
+ return "";\r
+ String[] split = str.split(";", 2);\r
+ String rez = split[0];\r
+ String comment = "";\r
+ // removes the comments\r
+ if (translateComments && split.length > 1)\r
+ comment = createComment(split[1]);\r
+ if (rez.compareTo("") != 0) {\r
+ // if there is a non-comment part\r
+ String[] parts = rez.split("[\t ,]");\r
+ // separators are whitespace: tab, space and comma\r
+ ArrayList<String> com = new ArrayList<String>();\r
+ for (String s : parts)\r
+ if (s.compareTo("") != 0 && s != null)\r
+ com.add(s);\r
+ rez = "";\r
+ String a, b;\r
+ // special case, we are processing lines in a macro definition\r
+ if (inMacro) {\r
+ Iterator<String> it = com.iterator();\r
+ while (it.hasNext())\r
+ if (it.next().compareTo("endm") == 0)\r
+ inMacro = false;\r
+ return createComment(str, C_SPEC) + "\n";\r
+ }\r
+ // by this time, all the real words should be in the com array\r
+ int i = 0;\r
+ boolean work = true;\r
+ // debugPrint(com);\r
+ while (i < com.size() && work) {\r
+ String s = com.get(i).toLowerCase();\r
+ if (s.endsWith(":")) { // should represent a label\r
+ s = s.substring(0, s.length() - 1);\r
+ rez += "CALL " + s + "\n END\n";\r
+ rez += s + " == ";\r
+ // labelfound = true;\r
+ } else\r
+ // ------------------------------------------------------------\r
+ // procedures, calls and similar activities\r
+ if (s.compareTo("proc") == 0) {\r
+ // if (labelfound)\r
+ rez += "CALL Z; SKIP END \n";\r
+ a = com.get(i - 1);\r
+ rez += a + " == ";\r
+ b = PROCEDURE_INTERNAL_SYS;\r
+ rez += "\nACTIONS " + b + ": \n";\r
+ rez += b + " == ";\r
+ inProcedure = true;\r
+ currentProcName = a;\r
+ } else if (s.compareTo("endp") == 0) {\r
+ rez += " SKIP END\n ENDACTIONS\n END\n dummy" + nKnownC\r
+ + " == ";\r
+ inProcedure = false;\r
+ } else if (s.compareTo("ret") == 0) {\r
+ rez += " CALL Z;";\r
+ } else if (s.compareTo("call") == 0) {\r
+ a = com.get(++i);\r
+ // check for recursive calls, don't do outside of current \r
+ // action system\r
+ if (inProcedure && currentProcName.equals(a))\r
+ a = PROCEDURE_INTERNAL_SYS;\r
+ rez += "CALL " + a + ";";\r
+ } else\r
+ // segments and other special assembler directives\r
+ if (s.charAt(0) == '.') { //\r
+ if (s.compareTo(".code") == 0) {\r
+ rez = CODE_SEG_START;\r
+ mode = MODE_CODE;\r
+ } else if (s.compareTo(".data") == 0) {\r
+ rez = " ";\r
+ mode = MODE_DATA;\r
+ } else if (s.compareTo(".stack") == 0) {\r
+ rez = " ";\r
+ mode = MODE_STACK;\r
+ } else if (s.startsWith(".model")) {\r
+ if (!s.toLowerCase().endsWith("small")) {\r
+ rez += createComment(\r
+ "other models than small not supported :: "\r
+ + split[0],\r
+ C_SPEC);\r
+ nUnknownD++;\r
+ mode = MODE_0;\r
+ }\r
+ } else {\r
+ rez += createComment(\r
+ "directive not supported :: " + split[0],\r
+ C_SPEC);\r
+ nUnknownD++;\r
+ mode = MODE_0;\r
+ }\r
+ work = false;\r
+ } else if (s.compareTo("assume") == 0) {\r
+ rez += createComment(\r
+ "ASSUME commands not supported :: " + split[0],\r
+ C_SPEC);\r
+ nUnknownD++;\r
+ work = false;\r
+ } else if (s.compareTo("segment") == 0) {\r
+ String segn = com.get(i - 1).toLowerCase();\r
+ if (segn.compareTo("cseg") == 0\r
+ || segn.compareTo("code") == 0\r
+ || segn.compareTo("code_seg") == 0) {\r
+ rez += CODE_SEG_START;\r
+ mode = MODE_CODE;\r
+ } else if (segn.compareTo("dseg") == 0\r
+ || segn.compareTo("data_seg") == 0\r
+ || segn.compareTo("data") == 0) {\r
+ rez += " ";\r
+ mode = MODE_DATA;\r
+ } else if (segn.compareTo("sseg") == 0\r
+ || segn.compareTo("stack_seg") == 0\r
+ || segn.compareTo("stack") == 0) {\r
+ rez += " ";\r
+ mode = MODE_STACK;\r
+ } else {\r
+ rez += createComment(\r
+ "unsuported segment type :: " + split[0],\r
+ C_SPEC);\r
+ nUnknownD++;\r
+ mode = MODE_0;\r
+ }\r
+ work = false;\r
+ } else if (s.compareTo("ends") == 0) { // segment end\r
+ if (i > 0) {\r
+ String segn = com.get(i - 1).toLowerCase();\r
+ if (segn.compareTo("cseg") == 0\r
+ || segn.compareTo("code_seg") == 0\r
+ || segn.compareTo("code") == 0\r
+ || segn.compareTo("dseg") == 0\r
+ || segn.compareTo("data") == 0\r
+ || segn.compareTo("data_seg") == 0\r
+ || segn.compareTo("sseg") == 0\r
+ || segn.compareTo("stack") == 0\r
+ || segn.compareTo("stack_seg") == 0) {\r
+ rez += createComment("end of segment " + segn,\r
+ C_SPEC);\r
+ mode = MODE_0;\r
+ } else {\r
+ rez += createComment(\r
+ "unsuported segment type :: " + split[0],\r
+ C_SPEC);\r
+ nUnknownD++;\r
+ }\r
+ } else {\r
+ rez += createComment("end of segment", C_SPEC);\r
+ mode = MODE_0;\r
+ }\r
+ work = false;\r
+ } else\r
+ // macro ideas ----\r
+ if (s.compareTo("macro") == 0) {\r
+ rez += createComment(\r
+ "found macro definition - macros unsuported",\r
+ C_ERR);\r
+ nUnknownC++;\r
+ inMacro = true;\r
+ work = false;\r
+ } else if (s.compareTo("endm") == 0) {\r
+ rez += createComment(\r
+ "found macro definition end - macros unsuported",\r
+ C_ERR);\r
+ nUnknownC++;\r
+ work = false;\r
+ } else\r
+\r
+ /*\r
+ * ------------------------------\r
+ * \r
+ * special macro names translated directly\r
+ */\r
+ if ((s.compareTo("print_str") == 0\r
+ || s.compareTo("print_num") == 0\r
+ || s.compareTo("print_char") == 0)\r
+ && com.get(i + 1).compareTo("macro") != 0) { \r
+ rez += "PRINFLUSH(" + com.get(i + 1) + ");";\r
+\r
+ work = false;\r
+ } else if (s.compareTo("print_new_line") == 0\r
+ && (com.size() <= i + 1\r
+ || com.get(i + 1).compareTo("macro") != 0)) { \r
+ rez += "PRINT(\"\");";\r
+\r
+ work = false;\r
+ } else if (s.compareTo("read_str") == 0\r
+ && com.get(i + 1).compareTo("macro") != 0) { \r
+ rez += "@Read_Line_Proc(VAR " + com.get(i + 1)\r
+ + ", Standard_Input_Port);";\r
+\r
+ work = false;\r
+ } else if (s.compareTo("read_num") == 0\r
+ && com.get(i + 1).compareTo("macro") != 0) { \r
+ rez += "@Read_Line_Proc(VAR t_e_m_p, Standard_Input_Port);\n";\r
+ rez += com.get(i + 1) + " := @String_To_Num(t_e_m_p);";\r
+\r
+ work = false;\r
+ } else if (s.compareTo("end_execution") == 0\r
+ && (com.size() <= i + 1\r
+ || com.get(i + 1).compareTo("macro") != 0)) { \r
+ rez += "CALL Z;";\r
+\r
+ work = false;\r
+ } else\r
+\r
+ // ---------------------------------------\r
+ // operators and similar commands\r
+ if (s.compareTo("mov") == 0) {\r
+ a = com.get(i + 1);\r
+ b = com.get(i + 2).toLowerCase();\r
+ if ((b.compareTo("@data") == 0)\r
+ || (b.compareTo("dseg") == 0)) {\r
+ rez += createComment("unneeded DATA segment fixes",\r
+ C_SPEC);\r
+ work = false;\r
+ } else {// rez += getOverflow(a);\r
+ rez += formatDst(a) + " := " + formatParam(b) + ";";\r
+ rez += getXRegisterFix(a);\r
+ work = false;\r
+ }\r
+ } else if (s.compareTo("add") == 0 || s.compareTo("adc") == 0) {\r
+ a = com.get(i + 1);\r
+ b = com.get(i + 2);\r
+ rez += getOverflow(a);\r
+ rez += formatDst(a) + " := " + formatParam(a) + " + "\r
+ + formatParam(b) + ";\n";\r
+ if (s.compareTo("adc") == 0)\r
+ rez += formatDst(a) + " := " + formatParam(a) + " + "\r
+ + " + flag_c;\n";\r
+ rez += "IF " + formatDst(a) + " >= overflow THEN "\r
+ + formatDst(a) + " := " + formatDst(a)\r
+ + " MOD overflow; flag_o :=1; flag_c := 1; ELSE flag_o :=0; flag_c := 0; FI;";\r
+ rez += getXRegisterFix(a);\r
+ work = false;\r
+ } else if (s.compareTo("sub") == 0 || s.compareTo("cmp") == 0) {\r
+ a = com.get(i + 1);\r
+ b = com.get(i + 2);\r
+ // rez += getOverflow(a);\r
+ rez += "IF " + formatParam(a) + " = " + formatParam(b)\r
+ + " THEN\n\t flag_z := 1\n ELSE\n\t flag_z := 0\n FI; ";\r
+ rez += "IF " + formatParam(a) + " < " + formatParam(b)\r
+ + " THEN\n\t flag_c := 1\n ELSE\n\t flag_c := 0\n FI; ";\r
+ if (s.compareTo("sub") == 0)\r
+ rez += formatDst(a) + " := " + formatParam(a) + " - "\r
+ + formatParam(b) + ";";\r
+ work = false;\r
+ } else if (s.compareTo("inc") == 0) {\r
+ a = com.get(i + 1);\r
+ rez += getOverflow(a);\r
+ rez += formatDst(a) + " := " + formatParam(a) + " + 1;";\r
+ rez += getXRegisterFix(a);\r
+ work = false;\r
+ } else if (s.compareTo("dec") == 0) {\r
+ a = com.get(i + 1);\r
+ rez += getOverflow(a);\r
+ rez += formatDst(a) + " := " + formatParam(a) + " - 1;";\r
+ rez += getXRegisterFix(a);\r
+ work = false;\r
+ } else if (s.compareTo("shr") == 0) {\r
+ a = com.get(i + 1);\r
+ // rez += getOverflow(a);\r
+ rez += "IF " + formatParam(a) + " MOD 2 = 1 THEN "\r
+ + " flag_c := 1; ELSE flag_c := 0; FI;";\r
+ rez += formatDst(a) + " := " + formatParam(a) + " DIV 2;";\r
+ rez += getXRegisterFix(a);\r
+ work = false;\r
+ } else if (s.compareTo("shl") == 0) {\r
+ a = com.get(i + 1);\r
+ rez += getOverflow(a);\r
+ rez += formatDst(a) + " := " + formatParam(a) + " * 2;";\r
+ rez += "IF " + formatDst(a) + " >= overflow THEN "\r
+ + formatDst(a) + " := " + formatDst(a)\r
+ + " MOD overflow; flag_o :=1; flag_c := 1; ELSE flag_o :=0; flag_c := 0; FI;";\r
+ rez += getXRegisterFix(a);\r
+ work = false;\r
+ } else if (s.compareTo("xchg") == 0) {\r
+ a = com.get(i + 1);\r
+ b = com.get(i + 2);\r
+ rez += "< " + formatDst(a) + " := " + formatParam(b) + ", "\r
+ + formatDst(b) + " := " + formatParam(a) + " >;";\r
+ rez += getXRegisterFix(a);\r
+ work = false;\r
+ } else\r
+ // logical exp\r
+ if (s.compareTo("and") == 0) {\r
+ // rez += com.get(i+1)+" := "+com.get(i+1)+" AND\r
+ // "+formatParam(com.get(i+2))+";";\r
+ rez += createComment(\r
+ "and not implemented yet :: " + split[0], C_ERR);\r
+ nUnknownC++;\r
+ work = false;\r
+ } else if (s.compareTo("xor") == 0) {\r
+ a = com.get(i + 1);\r
+ b = formatParam(com.get(i + 2));\r
+ if (a.compareTo(b) == 0)\r
+ rez += a + " := 0;";\r
+ else {\r
+ rez += createComment(\r
+ "xor not implemnted yet :: " + split[0], C_ERR);\r
+ // a+" := ("+a+" AND NOT "+b+") OR (NOT "+a+" AND "+b+"\r
+ // );");\r
+ nUnknownC++;\r
+ }\r
+ work = false;\r
+ } else if (s.compareTo("not") == 0) {\r
+ // rez += com.get(i+1)+" := NOT "+com.get(i+1)+";";\r
+ rez += createComment(\r
+ "NOT not implemented yet :: " + split[0], C_ERR);\r
+ nUnknownC++;\r
+ work = false;\r
+ } else\r
+ // jumps\r
+ if (s.compareTo("jmp") == 0) {\r
+ rez += "CALL " + com.get(i + 1) + ";";\r
+ work = false;\r
+ } else if (s.compareTo("je") == 0 || s.compareTo("jz") == 0) {\r
+ rez += "IF flag_z = 1 THEN CALL " + com.get(i + 1) + " FI;";\r
+ work = false;\r
+ } else if (s.compareTo("jne") == 0 || s.compareTo("jnz") == 0) {\r
+ rez += "IF flag_z = 0 THEN CALL " + com.get(i + 1) + " FI;";\r
+ work = false;\r
+ } else if (s.compareTo("ja") == 0) {\r
+ rez += "IF flag_z = 0 AND flag_c = 0 THEN CALL "\r
+ + com.get(i + 1) + " FI;";\r
+ work = false;\r
+ } else if (s.compareTo("jae") == 0 || s.compareTo("jnc") == 0) {\r
+ rez += "IF flag_c = 0 THEN CALL " + com.get(i + 1) + " FI;";\r
+ work = false;\r
+ } else if (s.compareTo("jb") == 0) {\r
+ rez += "IF flag_c = 1 THEN CALL " + com.get(i + 1) + " FI;";\r
+ work = false;\r
+ } else if (s.compareTo("jcxz") == 0) {\r
+ rez += "IF cx = 0 THEN CALL " + com.get(i + 1) + " FI;";\r
+ work = false;\r
+ } else if (s.compareTo("jo") == 0) {\r
+ rez += "IF flag_o = 1 THEN CALL " + com.get(i + 1) + " FI;";\r
+ work = false;\r
+ } else if (s.compareTo("loop") == 0) {\r
+ rez += "cx := cx - 1;\n";\r
+ rez += "IF cx>0 THEN CALL " + com.get(i + 1)\r
+ + " ELSE CALL dummy" + nKnownC + " FI\n";\r
+ rez += "END\ndummy" + nKnownC + " ==";\r
+ work = false;\r
+ } else\r
+\r
+ // end and other\r
+ if (s.compareTo("end") == 0) {\r
+ // TODO parse the optional entry label that comes with end\r
+ rez += createComment("program end");\r
+ work = false;\r
+ } else if (s.compareTo("nop") == 0) {\r
+ rez += "SKIP;";\r
+ work = false;\r
+ } else\r
+\r
+ // stack\r
+ if (s.compareTo("pop") == 0) {\r
+ if (translateToPopPush) {\r
+ rez += "POP(" + formatDst(com.get(i + 1)) + ", stack);";\r
+ } else {\r
+ rez += formatDst(com.get(i + 1)) + " := HEAD(stack);\n";\r
+ rez += "stack := TAIL(stack);";\r
+ }\r
+ rez += getXRegisterFix(com.get(i + 1));\r
+ work = false;\r
+ } else if (s.compareTo("push") == 0) {\r
+ if (translateToPopPush) {\r
+ rez += "PUSH(stack, " + formatParam(com.get(i + 1))\r
+ + ");";\r
+ } else {\r
+ rez += "stack := < " + formatParam(com.get(i + 1))\r
+ + " > ++ stack;";\r
+ }\r
+ work = false;\r
+ } else\r
+ // var definitions\r
+ if (s.compareTo("db") == 0 || s.compareTo("dw") == 0) {\r
+ if (mode == MODE_DATA) {\r
+ if (com.size() == i + 2) {\r
+ rez += "\t " + com.get(i - 1) + " := "\r
+ + formatParam(com.get(i + 1)) + ",";\r
+ } else {// array\r
+ rez += "\t " + com.get(i - 1) + " := < "\r
+ + formatParam(com.get(i + 1));\r
+ for (int j = i + 2; j < com.size(); j++)\r
+ rez += "," + formatParam(com.get(j));\r
+ rez += " >,";\r
+ }\r
+ } else {\r
+\r
+ }\r
+ }\r
+ i++;\r
+ }\r
+ if (rez.compareTo("") == 0 && com.size() > 0) {\r
+ rez = createComment(" unkown command:" + split[0], C_ERR);\r
+ nUnknownC++;\r
+ } else\r
+ nKnownC++; // this now counts the directives too...\r
+ }\r
+ return rez + " " + comment + "\n";\r
+\r
+ }\r
+\r
+ /**\r
+ * Converts an asm file to a wsl file. It also prints out the number of\r
+ * unsupported commands.\r
+ */\r
+ public void convertAFile(File f) {\r
+ try {\r
+ BufferedReader in = new BufferedReader(\r
+ new InputStreamReader(new FileInputStream(f)));\r
+ String str = in.readLine(), rez = f.getPath();\r
+ if (rez.toLowerCase().endsWith(".asm"))\r
+ rez = rez.substring(0, rez.length() - 4);\r
+ PrintWriter out = new PrintWriter(\r
+ new OutputStreamWriter(new FileOutputStream(rez + ".wsl")));\r
+ nUnknownD = 0;\r
+ nUnknownC = 0;\r
+ nKnownC = 0;\r
+ StringBuilder[] sbs = new StringBuilder[N_MODES];\r
+ for (int i = 0; i < N_MODES; i++)\r
+ sbs[i] = new StringBuilder();\r
+ while (str != null) {\r
+ rez = processLine(str);\r
+ if (originalInComments)\r
+ sbs[mode].append(createComment(str, C_OC) + "\n");\r
+ sbs[mode].append(rez);\r
+ str = in.readLine();\r
+ }\r
+ sbs[MODE_CODE].append(CODE_SEG_END);\r
+ if (addMemoryDump)\r
+ sbs[MODE_CODE].append("memdump();");\r
+ sbs[MODE_DATA].append(DATA_SEG_END);\r
+ // remove comments from dataseg\r
+ String datastr = sbs[MODE_DATA].toString()\r
+ .replaceAll("C:\"(.*?)\";\n?", "");\r
+ in.close();\r
+ out.print(getStandardStart());\r
+ out.print(sbs[MODE_0]);\r
+ out.print(DATA_SEG_START);\r
+ out.print(datastr); // out.print(sbs[MODE_DATA]);\r
+ out.print(sbs[MODE_CODE]);\r
+ out.print(getStandardEnd());\r
+ out.close();\r
+ if (nUnknownD > 0)\r
+ System.out.println("warning: " + nUnknownD\r
+ + " unkown/unsuported directives were found");\r
+ if (nUnknownC > 0)\r
+ System.out.println("errors : " + nUnknownC\r
+ + " unkown/unsuported commands were found");\r
+ System.out.println(nKnownC + " commands translated");\r
+ } catch (Exception e) {\r
+ System.err.println("error in conversion:");\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+ public void run(String[] args) {\r
+ if (args.length == 0) {\r
+ System.out.println("Assembler to WSL converter. v " + versionN\r
+ + ", by Doni Pracner");\r
+ System.out.println("usage:\n\t asm2wsl {-option[ +-]} filename");\r
+ System.out.println("options: (def value in parenthesis)");\r
+ System.out.println("\t -oc : orignal code in comments ("\r
+ + (originalInComments ? "+" : "-") + ")");\r
+ System.out.println("\t -c : translate comments ("\r
+ + (translateComments ? "+" : "-") + ")");\r
+ System.out.println("\t -dump : add memory dump commands to end ("\r
+ + (addMemoryDump ? "+" : "-") + ")");\r
+ } else {\r
+ if (args[0].compareTo("-h") == 0\r
+ || args[0].compareTo("--help") == 0) {\r
+ run(new String[0]);\r
+ return;\r
+ }\r
+ int i = 0;\r
+ while (i < args.length && args[i].charAt(0) == '-') {\r
+ if (args[i].startsWith("-oc")) {\r
+ if (args[i].length() == 4)\r
+ originalInComments = args[i].charAt(3) == '+';\r
+ else\r
+ originalInComments = true;\r
+ } else if (args[i].startsWith("-c")) {\r
+ if (args[i].length() == 3)\r
+ translateComments = args[i].charAt(2) == '+';\r
+ else\r
+ translateComments = true;\r
+ } else if (args[i].startsWith("-dump")) {\r
+ addMemoryDump = true;\r
+ if (args[i].length() == 6 && args[i].charAt(5) == '-')\r
+ addMemoryDump = false;\r
+ }\r
+ i++;\r
+ }\r
+\r
+ if (i >= args.length) {\r
+ System.out.println("no filename supplied");\r
+ System.exit(2);\r
+ }\r
+ File f = new File(args[i]);\r
+ if (f.exists()) {\r
+ Calendar now = Calendar.getInstance();\r
+ convertAFile(f);\r
+ long mili = Calendar.getInstance().getTimeInMillis()\r
+ - now.getTimeInMillis();\r
+ System.out.println("conversion time:" + mili + " ms");\r
+ } else\r
+ System.out.println("file does not exist");\r
+ }\r
+ }\r
+\r
+ public static void main(String[] args) {\r
+ new asm2wsl().run(args);\r
+ }\r
+}\r
diff --git a/tests/array-sum-input.1.txt b/tests/array-sum-input.1.txt
--- /dev/null
@@ -0,0 +1,4 @@
+4
+3
+22
+111
\ No newline at end of file
diff --git a/tests/array-sum-input.2.txt b/tests/array-sum-input.2.txt
--- /dev/null
@@ -0,0 +1,2 @@
+1
+15
diff --git a/tests/array-sum-input.3.txt b/tests/array-sum-input.3.txt
--- /dev/null
@@ -0,0 +1 @@
+0
diff --git a/tests/array-sum-input.4.txt b/tests/array-sum-input.4.txt
--- /dev/null
@@ -0,0 +1 @@
+22
\ No newline at end of file
diff --git a/tests/array-sum-predef.txt b/tests/array-sum-predef.txt
diff --git a/tests/fakt.txt b/tests/fakt.txt
diff --git a/tests/gcd-input.1.txt b/tests/gcd-input.1.txt
--- /dev/null
+++ b/tests/gcd-input.1.txt
@@ -0,0 +1,2 @@
+25
+15
diff --git a/tests/gcd-input.2.txt b/tests/gcd-input.2.txt
--- /dev/null
+++ b/tests/gcd-input.2.txt
@@ -0,0 +1,2 @@
+15
+25
diff --git a/tests/gcd-input.3.txt b/tests/gcd-input.3.txt
--- /dev/null
+++ b/tests/gcd-input.3.txt
@@ -0,0 +1,2 @@
+17
+13
diff --git a/tests/gcd-input.4.txt b/tests/gcd-input.4.txt
--- /dev/null
+++ b/tests/gcd-input.4.txt
@@ -0,0 +1,2 @@
+12
+12
diff --git a/tests/gcd-predef.txt b/tests/gcd-predef.txt
diff --git a/tests/procgcd.txt b/tests/procgcd.txt
diff --git a/tests/rek-gcd-input.1.txt b/tests/rek-gcd-input.1.txt
--- /dev/null
@@ -0,0 +1,2 @@
+25
+15
diff --git a/tests/rek-gcd-input.2.txt b/tests/rek-gcd-input.2.txt
--- /dev/null
@@ -0,0 +1,2 @@
+15
+25
diff --git a/tests/rek-gcd-input.3.txt b/tests/rek-gcd-input.3.txt
--- /dev/null
@@ -0,0 +1,2 @@
+17
+13
diff --git a/tests/rek-gcd-input.4.txt b/tests/rek-gcd-input.4.txt
--- /dev/null
@@ -0,0 +1,2 @@
+12
+12
diff --git a/tests/rek-gcd-predef.txt b/tests/rek-gcd-predef.txt
diff --git a/tests/sumn-stack-prompt.1.txt b/tests/sumn-stack-prompt.1.txt
--- /dev/null
@@ -0,0 +1,4 @@
+4
+3
+22
+111
\ No newline at end of file
diff --git a/tests/sumn-stack-prompt.2.txt b/tests/sumn-stack-prompt.2.txt
--- /dev/null
@@ -0,0 +1,2 @@
+1
+15
diff --git a/tests/sumn-stack-prompt.3.txt b/tests/sumn-stack-prompt.3.txt
--- /dev/null
@@ -0,0 +1 @@
+0
diff --git a/update-samples-without-macros.sh b/update-samples-without-macros.sh
--- /dev/null
@@ -0,0 +1,8 @@
+#!/bin/bash
+# copy from samples-with-macros and remove the macros segment in the samples folder
+
+cp samples-with-macros/*.asm samples/
+sed -i \
+ -e '/#macro-commands-start/,/#macro-commands-end/ c ;#macros-removed-from-listing' \
+ -e '/#extra-start/,/#extra-end/ d' \
+ samples/*.asm
\ No newline at end of file