Author Topic: Asmc source and binaries  (Read 1295 times)

nidud

  • Member
  • *****
  • Posts: 1228
    • https://github.com/nidud/asmc
Asmc source and binaries
« on: January 10, 2017, 03:13:07 AM »
Source and binaries for Asmc is now available at GitHub:

https://github.com/nidud/asmc

The package is configured to work "out of the box" but it's recommended to tweak the console settings for optimal performance.

Console applications is best managed by simply adding a shortcut to the program, in this case to the file DZ.EXE in the root directory of the package. After the shortcut is created, right-click and select Properties. Open the Font tab and select a proper font and font size for the console window.

I didn't find the keyboard settings directly in the Win7 Control panel but the search[keyboard] option found the Keyboard Properties tab. The keyboard is normally slow in the console so the Keyboard Delay should be set to Short and Repeat Rate to Fast for best performance.

The environment for the shell is set as follows:
Code: [Select]
[Environ]
0=AsmcDir=%DZ%
1=LIB=%DZ%\lib
2=INCLUDE=%DZ%\include
3=WATCOM=C:\WATCOM

[Path]
0=%AsmcDir%\bin
1=C:\VC\bin
2=%WATCOM%\BINNT
3=%WATCOM%\BINW
4=C:\jWasm
5=%PATH%

Note that Watcom provide clones for some of the MS tools, so VC should for this reason be defined before Watcom.

caballero

  • Member
  • ****
  • Posts: 674
    • Abre Ojos Ensamblador
Re: Asmc source and binaries
« Reply #1 on: January 10, 2017, 03:38:42 AM »
What is asmc if I may ask?
En un lugar de la Mancha de cuyo nombre no quiero acordarme

nidud

  • Member
  • *****
  • Posts: 1228
    • https://github.com/nidud/asmc
Re: Asmc source and binaries
« Reply #2 on: January 10, 2017, 04:43:27 AM »
What is asmc if I may ask?

Asmc is basically a modified version of JWasm made in 2011. It was used as a TASM clone to maintain some DOS tools at the time.

https://github.com/nidud/asmc/blob/master/source/dos/tasm/tasm.asm

I later added some enhancement to the HLL section and a few other things, so I have been playing with it for some time. However the features added so far seems stable so in that sense the playtime has come to a conclusion in a somewhat usable product.

Some more info from the help file:

Asmc Macro Assembler Reference

This lists some of the differences between Asmc, JWasm, and Masm.

Asmc Extensions

The main goal with Asmc is an attempt to provide more readability to the assembly language based on Masm syntax but at the same time keep compatibility with existing source code. In order to achieve this some of the main core of the assembler has to be rewritten and the HLL section enhanced as discussed below.

Parsing of labels

All expansions are pre-processed by the assembler and this may expand macros and other directives before labels. If a macro is added at the same line as a label this may fail.

Example:

Code: [Select]
foo macro reg
bswap reg
exitm <reg>
endm

do: mov eax,foo( eax )
...
mov ecx,"3210"
jmp do

As a result the code produced by the macro will be expanded above the label and thus the jump will fail.

Code: [Select]
bswap ecx
do: mov eax,ecx
...

Asmc will expand the line left to right in this case.

Expansion of macros

The label issue becomes a problem in the HLL section where labels are created later:

   .WHILE macro(...)

Asmc will for this reason delay expansion of macros in some of the HLL directives until labels are created. This include .WHILE, .ELSEIF, and .CASE.

The invoke directive

In Asmc a macro is handled at the same level as a procedure. The header file may then control the expansion:
Code: [Select]
ifdef __INLINE__
strlen macro string
...
endm
else
strlen proto :dword
endif

This is achieved by simply excluding invoke as appose to allow invocations of macros.

   strlen( esi )


Asmc sees the combination of a procedure followed by an open bracket as invoke. Empty brackets will be given special handling if the token in front is not a macro.
Code: [Select]
plabel proto
extern elabel:dword
clabel:
call eax
call plabel
call elabel
call clabel
call xlabel

eax()
plabel()
elabel()
clabel()
xlabel()
xlabel:

This simple solution avoids breaking any existing code with a few exceptions: Masm allows brackets to access memory.

   .if edx < foo( 1 )
   ; MASM: cmp edx,foo+1
   ; ASMC: invoke foo, 1 : cmp edx,eax

So square brackets should be used for accessing memory and round brackets to execute. However, an error must then be issued if Asmc extensions are turned off and labels are accessed using round brackets to ensure compatibility.

The inside of brackets may be recursive used at any length including C-strings. However, the return code for a procedure is [R|E]AX so there is a limit with regards to OR/AND testing of nested functions.

   .if foo( bar( 1 ), 2 ) == TRUE


Handling of strings

Given "quoted strings" may be used as arguments, or in general as a const value, C-strings are limited to be used inside brackets of a procedure.

   .if fopen( "readme.txt", "rt" )


@CStr( string )

Macro function that creates a string in the .DATA segment. The macro accepts C-escape characters in the string. Strings are added to a stack and reused if duplicated strings are found. The macro returns offset string.

Example:
Code: [Select]
mov eax,@CStr( "\tCreate a \"C\" string: %s%d\n" )
mov ebx,@CStr( "string: %s%d\n" )
mov ecx,@CStr( "%s%d\n" )
mov edx,@CStr( "%d\n" )
mov edi,@CStr( "\n" )

Generated code:
Code: [Select]
.data
DS0000 db 9,"Create a ",'"',"C",'"'," string: %s%d",10,0
.code
mov eax,offset DS0000
mov ebx,offset DS0000[14]
mov ecx,offset DS0000[22]
mov edx,offset DS0000[24]
mov edi,offset DS0000[26]

@Date

The system date in the format yyyy-mm-dd (text macro).

.SWITCH

The switch comes in three main variants: a structured switch, as in Pascal, which takes exactly one branch, an unstructured switch, as in C, which functions as a type of goto, and a control table switch with the added possibility of testing for combinations of input values, using boolean style AND/OR conditions, and potentially calling subroutines instead of just a single set of values.

The control table switch is declared with no arguments and each .CASE directive does all the testing.
Code: [Select]
    .switch
      .case strchr( esi, '<' )
      .case strchr( esi, '>' )
    jmp around
      ...
    .endsw

The unstructured switch works as a regular C switch where each .CASE directive is just a label.
Code: [Select]
    .switch eax
      .case 0: .repeat : movsb
      .case 7: movsb
      .case 6: movsb
      .case 5: movsb
      .case 4: movsb
      .case 3: movsb
      .case 2: movsb
      .case 1: movsb : .untilcxz
    .endsw

The structured switch works as a regular Pascal switch where each .CASE directive is a closed branch.
Code: [Select]
    .switch eax
      .case 1: printf("Gold medal")
      .case 2: printf("Silver medal")
      .case 3: printf("Bronze medal")
      .default
  printf("Better luck next time")
    .endsw

.CASE

Case opens a case statement. The case statement compares the value of an ordinal expression to each selector, which can be a constant, a subrange, or a list of them separated by commas.

The selector field is separated from action field by Colon or a new line.
Code: [Select]
.CASE 1: mov ax,2 : .ENDC
.CASE 2
      mov ax,3
      .ENDC
.CASE al
.CASE 0,1,4,7
.CASE 0..9

In the control table switch .CASE is equal to .IF:
Code: [Select]
.CASE al
.CASE ax <= 2 && !bx

.ENDC

.ENDC closes a .CASE statement.

The name was separated from BREAK to have more flexibility with regards to control flow of loops. However, ENDC have the same qualities as BREAK and thus can be used in combination with .IF:

   .ENDC .IF al == 2


.DEFAULT

.DEFAULT executes when none of the other cases match the control expression.

.ENDSW

.ENDSW closes a .SWITCH statement.

HSE

  • Member
  • ***
  • Posts: 454
  • <AMD>< 7-32>
Re: Asmc source and binaries
« Reply #3 on: January 10, 2017, 06:12:10 AM »
Hi Nidud!!

Just testing a ObjAsm32 project (wich have macros .for .switch, etc) I think /Xc is not disabling .switch. 

Of course if the option disable .if, .while, .repeat, etc there is another problem.

Regards.

nidud

  • Member
  • *****
  • Posts: 1228
    • https://github.com/nidud/asmc
Re: Asmc source and binaries
« Reply #4 on: January 10, 2017, 07:41:37 AM »
Just testing a ObjAsm32 project (wich have macros .for .switch, etc) I think /Xc is not disabling .switch. 

The extended directives will be a problem if you use them in this way, so I have to look into that.

Code: [Select]
ifdef __ASMC__
    option renamekeyword: <.switch>=@@switch
    option renamekeyword: <.case>=@@case
    option renamekeyword: <.endsw>=@@endsw
endif

Or the reverse logic:
Code: [Select]
ifndef __ASMC__
    option dotname

.switch macro arg
...
endm
.case macro arg
...
endm
.endsw macro
...
endm
endif

nidud

  • Member
  • *****
  • Posts: 1228
    • https://github.com/nidud/asmc
Re: Asmc source and binaries
« Reply #5 on: January 10, 2017, 07:59:02 AM »
So, the full list:
Code: [Select]
ifdef __ASMC__
    option asmc:off
    option nokeyword:<.switch>
    option nokeyword:<.case>
    option nokeyword:<.endc>
    option nokeyword:<.default>
    option nokeyword:<.endsw>
    option nokeyword:<.ifb>
    option nokeyword:<.ifw>
    option nokeyword:<.ifd>
    option nokeyword:<.assert>
    option nokeyword:<.assertb>
    option nokeyword:<.assertw>
    option nokeyword:<.assertd>
endif

nidud

  • Member
  • *****
  • Posts: 1228
    • https://github.com/nidud/asmc
Re: Asmc source and binaries
« Reply #6 on: January 10, 2017, 09:04:29 AM »
I updated the source and binary

https://github.com/nidud/asmc/commit/571c0913123d57ba2320b263d82f664f6d274ad1

test case using the switch /Xc
Code: [Select]
.486
.model flat
.code

        option dotname

.switch macro
endm
.case macro
endm
.endc macro
endm
.default macro
endm
.endsw macro
endm
.ifb macro
endm
.ifw macro
endm
.ifd macro
endm
.assert macro
endm
.assertb macro
endm
.assertw macro
endm
.assertd macro
endm

END

HSE

  • Member
  • ***
  • Posts: 454
  • <AMD>< 7-32>
Re: Asmc source and binaries
« Reply #7 on: January 10, 2017, 02:17:37 PM »
/Xc work perfect now  :t

With that option ObjAsm32 work fantastic.  :eusa_clap: :eusa_clap:

Apparently full compatiblity with M$, no length line problems, nor macro nest levels problems.   

                             

nidud

  • Member
  • *****
  • Posts: 1228
    • https://github.com/nidud/asmc
Re: Asmc source and binaries
« Reply #8 on: January 10, 2017, 09:23:08 PM »
 :t

This do however separate the switch /Xc from the OPTION ASMC:[ON|OFF]

The off option will keep the directives and the switch will still work, but using extended features will generate an error:
Code: [Select]
        foo proto
        option asmc:off
        .switch
          .case  (eax || edx) && ecx : nop : .endc
          .case !(eax || edx) && ecx : nop : .endc
          .case foo()
 error A2008: syntax error : )

HSE

  • Member
  • ***
  • Posts: 454
  • <AMD>< 7-32>
Re: Asmc source and binaries
« Reply #9 on: January 12, 2017, 01:06:55 AM »
Very interesting! With the nokeyword option it's posible to use the same command line options for M$ or HJwasm. In RadAsm I only change the assembler name  :t 

powershadow

  • Regular Member
  • *
  • Posts: 20
Re: Asmc source and binaries
« Reply #10 on: January 15, 2017, 10:56:12 PM »
Hi nidud.
Just downloaded asmc.exe for test it, and I already have a question.
Command-line /I - not supported anymore? I need use environment variable "include"?
I see asmc just add path from "/I" to the path of my project, this is incorrect.

Simple example:

.386
.model flat,stdcall
include windows.inc ; <<<< fatal error A1000: cannot open file: windows.inc

Command-line:
c:\jwasm\bin32\asmc.exe /c /coff /cp /I"c:\jwasm\Include" "test.asm"

It is bug or feature?

jj2007

  • Member
  • *****
  • Posts: 6906
  • Assembler is fun ;-)
    • MasmBasic
Re: Asmc source and binaries
« Reply #11 on: January 15, 2017, 11:00:13 PM »
include windows.inc ; <<<< fatal error A1000: cannot open file: windows.inc

Use \masm32\include\windows.inc

Or, even better:
include \masm32\include\masm32rt.inc

There is a reason why (almost) everybody here uses the \full\path without the drive letters: it works.

powershadow

  • Regular Member
  • *
  • Posts: 20
Re: Asmc source and binaries
« Reply #12 on: January 15, 2017, 11:15:44 PM »
There is a reason why (almost) everybody here uses the \full\path without the drive letters: it works.

Thanks for reply. I know it. I just ask if this bug or feature. I just opened example from masm32 and can't compile them without modify.

masm - file found.
jwasm - file found.
hjwasm - file found.
asmc - file NOT found, strange.

jj2007

  • Member
  • *****
  • Posts: 6906
  • Assembler is fun ;-)
    • MasmBasic
Re: Asmc source and binaries
« Reply #13 on: January 15, 2017, 11:24:24 PM »
OK, I see. This works:
Code: [Select]
C:\Masm32\MasmBasic\AscUser>\masm32\bin\asmc /c /coff /I"\Masm32\Include" testAsmC.asm
Doszip Macro Assembler Version 2.22
Portions Copyright (c) 1992-2002 Sybase, Inc. All Rights Reserved.

 Assembling: testAsmC.asm

... with this source:
Code: [Select]
.386
.model flat,stdcall
;include windows.inc ; <<<< fatal error A1000: cannot open file: windows.inc
.code
start:
  retn

end start

However, I get plenty of errors in all assemblers when trying to use both the command line include and the one after .model

Btw what's the state of play in your other thread? All problems fixed?

nidud

  • Member
  • *****
  • Posts: 1228
    • https://github.com/nidud/asmc
Re: Asmc source and binaries
« Reply #14 on: January 16, 2017, 02:58:17 AM »
Confirmed.

Quotes in command line arguments are not expanded in the same way in the RTL now used, so additional expansion was needed for switch -D, -I and -Fi used with -I"quoted text".

Link to the added changes:
https://github.com/nidud/asmc/commit/5471d03bbfced345c50b95dcecb1e6957fe18a95