Author Topic: More high level directives in ASMC and DOS  (Read 578 times)

nikkho

  • Regular Member
  • *
  • Posts: 12
More high level directives in ASMC and DOS
« on: June 07, 2017, 09:26:13 PM »
I already requested this in UASM, and they seem not to be very interested in 16 bit, so let me post that here too.

I am a former TASM user, than then moved to JWASM. I mainly develop DOS programs, and this is why I miss default DOS binaries, that were available under JWASM. Do you consider releaseing them too?

Also, since the time of TASM, I miss some high level/SMART directives that were available, for instance:
- FASTIMUL dest_reg, source_r/m, value
This instruction is much like the trinary IMUL operation available on the 80186, 80286, and 80386 processors. The dest_reg destination register is a WORD register (or it can be DWORD on the 80386). source_r/m is a register or memory address that must match the size of the destination. value is a fixed, signed constant multiplicand. FASTIMUL uses a combination of IMUL, MOV, NEG, SHL, ADD, and SUB instructions to perform its function. This function destroys the source register or memory address, and leaves the processor flags in an indeterminate state.

- SHL/SHR/RCL/RCR/ROL/ROR: When .8086 was used, it was unrolled such as SHR AX, 2, as SHR AX, 1 / SHR AX, 1.

- SETFLAG - a "smart-flag" instruction implementing OR

- TESTFLAG - a "smart-flag" instruction implementing TEST

- FLIPFLAG - a "smart-flag" instruction implementing XOR

- CLRFLAG - [bytepointer.com edit] I think this is a doc bug where the writers meant to specify MASKFLAG as CLRFLAG does not exist and likely never existed; there is no CLRFLAG identifier embedded within this version or any version of TASM; CLRFLAG is also not documented anywhere else but the one place it was ever mentioned: the keywords table for version 3.0.

- MASKFLAG (u) - a "smart-flag" instruction implementing AND; accidentally documented in the new keywords for version 3.0 table as CLRFLAG

- SETFIELD generates code that sets a value in a record field. Its syntax follows:

- GETFIELD retrieves data from a record field. It functions as the logical reverse of the SETFIELD instruction. Its syntax follows:               


As a bonus, I would like to see some kind of optional optimizations options, that if enabled will for instance replace, and give a warning message when done, about some inneficient casuistics:
 - mov ah, 3 / mov al, 5 => mov ax, 0305h
 - dec cx / cmp cx, 0 / je label => dec cx / je label
 - shl cx, 1 / shl cx, 1 => shl cx, 2 (if .186 or later)
 - cmp cx, 0 / je label => jcxz label
 - mov eax, 0 => xor eax, eax (if flags are not used)
 - cmp eax, 0 => test eax, eax (if flags are not used)
 - mov eax, -1 => or eax, -1 (if flags are not used)

Those would allow to get an extra performance boost while assembling with UASM from an automatic ASM generated listing, and why not, to automatically optimize some third party codes.

Reason to be it optional by using a command-line option and a directive, is of course that it could broke some internal code that could rely on timmings or code sizes.

Looking forward to hear from you.

nidud

  • Member
  • *****
  • Posts: 1386
    • https://github.com/nidud/asmc
Re: More high level directives in ASMC and DOS
« Reply #1 on: June 07, 2017, 11:31:35 PM »
Hi nikkho,

I already requested this in UASM, and they seem not to be very interested in 16 bit, so let me post that here too.

HJWasm/Uasm is mainly a 64-bit enhancement of Jwasm developed using the latest version of Microsoft Visual Studio. It focus mainly on newer hardware as AVX-512 and VEX implementation, so backward compatibility is not a high priority.

Asmc is built using command line tools, mainly the Open Watcom tool-chain as used to build Jwasm. It preserve  backward compatibility with both older version of Masm and Jwasm. The default compatibility mode for ML is version 8 but it include SSE and AVX instructions as well.

Quote
I am a former TASM user, than then moved to JWASM. I mainly develop DOS programs, and this is why I miss default DOS binaries, that were available under JWASM. Do you consider releaseing them too?

Do to all changes in Jwasm the DOS (Jwasmr) version become obsolete at one point so you wont be able to build it even with the latest versions of Jwasm, so all 16-bit related source is removed from Asmc.

Quote
Also, since the time of TASM, I miss some high level/SMART directives that were available, for instance:
- FASTIMUL dest_reg, source_r/m, value
This instruction is much like the trinary IMUL operation available on the 80186, 80286, and 80386 processors. The dest_reg destination register is a WORD register (or it can be DWORD on the 80386). source_r/m is a register or memory address that must match the size of the destination. value is a fixed, signed constant multiplicand. FASTIMUL uses a combination of IMUL, MOV, NEG, SHL, ADD, and SUB instructions to perform its function. This function destroys the source register or memory address, and leaves the processor flags in an indeterminate state.

There is no development for 16-bit code other than maintaining the compatibility that already exist, so you have to use macros or TASM for this.

Quote
- SHL/SHR/RCL/RCR/ROL/ROR: When .8086 was used, it was unrolled such as SHR AX, 2, as SHR AX, 1 / SHR AX, 1.

Well, it's possible..

Quote
- SETFLAG - a "smart-flag" instruction implementing OR
- TESTFLAG - a "smart-flag" instruction implementing TEST
- FLIPFLAG - a "smart-flag" instruction implementing XOR
- CLRFLAG - [bytepointer.com edit] I think this is a doc bug where the writers meant to specify MASKFLAG as CLRFLAG does not exist and likely never existed; there is no CLRFLAG identifier embedded within this version or any version of TASM; CLRFLAG is also not documented anywhere else but the one place it was ever mentioned: the keywords table for version 3.0.

- MASKFLAG (u) - a "smart-flag" instruction implementing AND; accidentally documented in the new keywords for version 3.0 table as CLRFLAG

- SETFIELD generates code that sets a value in a record field. Its syntax follows:

- GETFIELD retrieves data from a record field. It functions as the logical reverse of the SETFIELD instruction. Its syntax follows:

Code: [Select]
r0      RECORD fa:1,fb:1,fc:1
flag    r0 <1,0,1>

Code: [Select]
    or      flag,mask fa    ; SETFLAG
    test    flag,mask fb    ; TESTFLAG
    xor     flag,mask fc    ; FLIPFLAG

Quote
As a bonus, I would like to see some kind of optional optimizations options, that if enabled will for instance replace, and give a warning message when done, about some inneficient casuistics:
 - mov ah, 3 / mov al, 5 => mov ax, 0305h
 - dec cx / cmp cx, 0 / je label => dec cx / je label
 - shl cx, 1 / shl cx, 1 => shl cx, 2 (if .186 or later)
 - cmp cx, 0 / je label => jcxz label
 - mov eax, 0 => xor eax, eax (if flags are not used)
 - cmp eax, 0 => test eax, eax (if flags are not used)
 - mov eax, -1 => or eax, -1 (if flags are not used)

If you read the manual and look at sample code provided you will find many of these things implemented, but not in any form that break compatibility with existing code. Also keep in mind the difference between an assembler and a compiler: less nanny help  :P

nikkho

  • Regular Member
  • *
  • Posts: 12
Re: More high level directives in ASMC and DOS
« Reply #2 on: June 08, 2017, 01:40:15 AM »
Quote
- SHL/SHR/RCL/RCR/ROL/ROR: When .8086 was used, it was unrolled such as SHR AX, 2, as SHR AX, 1 / SHR AX, 1.

Would like to see it.

nikkho

  • Regular Member
  • *
  • Posts: 12
Re: More high level directives in ASMC and DOS
« Reply #3 on: June 23, 2017, 04:47:08 PM »
Quote
- SHL/SHR/RCL/RCR/ROL/ROR: When .8086 was used, it was unrolled such as SHR AX, 2, as SHR AX, 1 / SHR AX, 1.

Would like to see it.

Any update on this?

nidud

  • Member
  • *****
  • Posts: 1386
    • https://github.com/nidud/asmc
Re: More high level directives in ASMC and DOS
« Reply #4 on: June 24, 2017, 06:02:07 AM »
No I haven't looked into this yet. You may solve this using macros thought:

Code: [Select]
; 8086.INC--

    option renamekeyword: <shr>=@@shr
    option renamekeyword: <shl>=@@shl

shr macro reg, val
    repeat val
    @@shr reg,1
    endm
    endm

shl macro reg, val
    repeat val
    @@shl reg,1
    endm
    endm

Code: [Select]
    .model small

include 8086.inc

    .code

    shr ax,3
    shl bx,2

    end

nikkho

  • Regular Member
  • *
  • Posts: 12
Re: More high level directives in ASMC and DOS
« Reply #5 on: June 26, 2017, 04:09:52 AM »
No I haven't looked into this yet. You may solve this using macros thought:

Code: [Select]
; 8086.INC--

    option renamekeyword: <shr>=@@shr
    option renamekeyword: <shl>=@@shl

shr macro reg, val
    repeat val
    @@shr reg,1
    endm
    endm

shl macro reg, val
    repeat val
    @@shl reg,1
    endm
    endm

Code: [Select]
    .model small

include 8086.inc

    .code

    shr ax,3
    shl bx,2

    end

Thanks. But the issue here, is that it should be possible to check that val is an inmediate, and no CL, or CX.
Any hint?

nidud

  • Member
  • *****
  • Posts: 1386
    • https://github.com/nidud/asmc
Re: More high level directives in ASMC and DOS
« Reply #6 on: June 26, 2017, 05:12:52 AM »
Something like this maybe:
Code: [Select]
shr macro reg, val
ifidni <val>,<cl>
    @@shr reg,cl
else
    repeat val
    @@shr reg,1
    endm
endif
    endm

nikkho

  • Regular Member
  • *
  • Posts: 12
Re: More high level directives in ASMC and DOS
« Reply #7 on: June 26, 2017, 10:48:31 PM »
Something like this maybe:
Code: [Select]
shr macro reg, val
ifidni <val>,<cl>
    @@shr reg,cl
else
    repeat val
    @@shr reg,1
    endm
endif
    endm


Thank you. This is how it looks:
Code: [Select]
; 8086.INC--


;Lower than 186
if @cpu lt 10b
option renamekeyword: <shr>=@@shr
shr macro reg, val
ifidni <val>, <cl>
repeat val
@@shr reg, 1
endm
endif
endm

option renamekeyword: <shl>=@@shl
shl macro reg, val
ifidni <val>, <cl>
repeat val
@@shl reg, 1
endm
endif
endm

option renamekeyword: <shr>=@@shr
shr macro reg, val
ifidni <val>, <cl>
repeat val
@@shr reg, 1
endm
endif
endm

option renamekeyword: <sal>=@@sal
sal macro reg, val
ifidni <val>, <cl>
repeat val
@@sal reg, 1
endm
endif
endm

option renamekeyword: <ror>=@@ror
ror macro reg, val
ifidni <val>, <cl>
repeat val
@@ror reg, 1
endm
endif
endm

option renamekeyword: <rol>=@@rol
rol macro reg, val
ifidni <val>, <cl>
repeat val
@@rol reg, 1
endm
endif
endm

option renamekeyword: <rcr>=@@rcr
rcr macro reg, val
ifidni <val>, <cl>
repeat val
@@rcr reg, 1
endm
endif
endm

option renamekeyword: <rcl>=@@rcl
rcl macro reg, val
ifidni <val>, <cl>
repeat val
@@rcl reg, 1
endm
endif
endm
endif

nidud

  • Member
  • *****
  • Posts: 1386
    • https://github.com/nidud/asmc
Re: More high level directives in ASMC and DOS
« Reply #8 on: June 27, 2017, 12:25:04 AM »
8087 is set by default so the value is 0x0101
Code: [Select]
if ((@cpu and 0xF) eq 1)
 include 8086.inc
endif

And a missing "else"
Code: [Select]
shr macro reg, val
ifidni <val>, <cl>
repeat val
@@shr reg, 1
endm
endif
endm

Code: [Select]
shr macro reg, val
ifidni <val>, <cl>
@@shr reg, cl
else
repeat val
@@shr reg, 1
endm
endif
endm

nikkho

  • Regular Member
  • *
  • Posts: 12
Re: More high level directives in ASMC and DOS
« Reply #9 on: June 28, 2017, 12:00:36 AM »
That is perfect. I have updated it, and added movzx for lower than 386:

Code: [Select]
; SMART.INC--


;8086
if ((@cpu and 0xFF) eq 1)
option renamekeyword: <shl>=@@shl
shl macro reg, val
ifidni <val>, <cl>
@@shl reg, val
else
repeat val
@@shl reg, 1
endm
endif
endm

option renamekeyword: <shr>=@@shr
shr macro reg, val
ifidni <val>, <cl>
@@shr reg, val
else
repeat val
@@shr reg, 1
endm
endif
endm

option renamekeyword: <sal>=@@sal
sal macro reg, val
ifidni <val>, <cl>
@@sal reg, val
else
repeat val
@@sal reg, 1
endm
endif
endm

option renamekeyword: <sar>=@@sar
sar macro reg, val
ifidni <val>, <cl>
@@sar reg, val
else
repeat val
@@sar reg, 1
endm
endif
endm

option renamekeyword: <rol>=@@rol
rol macro reg, val
ifidni <val>, <cl>
@@rol reg, val
else

repeat val
@@rol reg, 1
endm
endif
endm

option renamekeyword: <ror>=@@ror
ror macro reg, val
ifidni <val>, <cl>
@@ror reg, val
else
repeat val
@@ror reg, 1
endm
endif
endm

option renamekeyword: <rcl>=@@rcl
rcl macro reg, val
ifidni <val>, <cl>
@@rcl reg, val
else
repeat val
@@rcl reg, 1
endm
endif
endm

option renamekeyword: <rcr>=@@rcr
rcr macro reg, val
ifidni <val>, <cl>
@@rcr reg, val
else
repeat val
@@rcr reg, 1
endm
endif
endm

endif



;Lower than 386
if ((@cpu and 0xFF) lt 1000b)
option renamekeyword: <movzx>=@@movzx
movzx macro reg, val
ifidni <reg>, <ax>
xor ah, ah
mov al, val
elseifidni <reg>, <bx>
xor bh, bh
mov bl, val
elseifidni <reg>, <cx>
xor ch, ch
mov cl, val
elseifidni <reg>, <dx>
xor dh, dh
mov dl, val
endif
endm
endif