Author Topic: Signed compare in HLL  (Read 1063 times)

nidud

  • Member
  • *****
  • Posts: 1386
    • https://github.com/nidud/asmc
Signed compare in HLL
« on: January 25, 2017, 01:14:53 PM »
Added signed compare .IFS, .IFSB, .IFSW, and .IFSD

Test case for 16/32/64-bit.

Basically turns an .IF <statement> to "signed" if the first operand is a register. Was intended for functions normally returning [R|E]AX, but will work on other registers as well.

Qsort example using a prototype defined in stdlib.inc
Code: [Select]
include stdlib.inc
include string.inc

.code

qsort PROC USES esi edi ebx p:PVOID, n:SIZE_T, w:SIZE_T, compare:LPQSORTCMD

local stack_level

mov eax,n
.if eax > 1

dec eax
mul w
mov esi,p
lea edi,[esi+eax]
mov stack_level,0

.while 1

mov ecx,w
lea eax,[edi+ecx] ; middle from (hi - lo) / 2
sub eax,esi

.if !ZERO?

sub edx,edx
div ecx
shr eax,1
mul ecx
.endif

lea ebx,[esi+eax]
.ifs compare( esi, ebx ) > 0

memxchg( esi, ebx, w )
.endif
.ifs compare( esi, edi ) > 0

memxchg( esi, edi, w )
.endif
.ifs compare( ebx, edi ) > 0

memxchg( ebx, edi, w )
.endif

mov p,esi
mov n,edi

.while 1

mov eax,w
add p,eax
.if p < edi

.continue .ifs compare( p, ebx ) <= 0
.endif

.while 1

mov eax,w
sub n,eax

.break .if n <= ebx
.break .ifs compare( n, ebx ) <= 0
.endw

mov edx,n
mov eax,p
.break .if edx < eax

memxchg( edx, eax, w )

.if ebx == n

mov ebx,p
.endif
.endw

mov eax,w
add n,eax

.while 1

mov eax,w
sub n,eax

.break .if n <= esi
.break .if compare( n, ebx )
.endw

mov edx,p
mov eax,n
sub eax,esi
mov ecx,edi
sub ecx,edx

.ifs eax < ecx

mov ecx,n

.if edx < edi

push edx
push edi
inc stack_level
.endif

.if esi < ecx

mov edi,ecx
.continue
.endif
.else
mov ecx,n

.if esi < ecx

push esi
push ecx
inc stack_level
.endif

.if edx < edi

mov esi,edx
.continue
.endif
.endif

.break .if !stack_level

dec stack_level
pop edi
pop esi
.endw
.endif
ret

qsort ENDP

END

jj2007

  • Member
  • *****
  • Posts: 7633
  • Assembler is fun ;-)
    • MasmBasic
Re: Signed compare in HLL
« Reply #1 on: January 25, 2017, 08:29:59 PM »
What is the difference between
Code: [Select]
.ifs compare( esi, ebx ) > 0and
Code: [Select]
.if sdword ptr esi>ebx?

nidud

  • Member
  • *****
  • Posts: 1386
    • https://github.com/nidud/asmc
Re: Signed compare in HLL
« Reply #2 on: January 26, 2017, 01:07:11 AM »
What is the difference between
Code: [Select]
.ifs compare( esi, ebx ) > 0and
Code: [Select]
.if sdword ptr esi>ebx?

Code: [Select]
0000003B                .ifs compare( esi, ebx ) > 0
0000003B  53                *    push ebx
0000003C  56                *    push esi
0000003D  FF5514            *    call compare
00000040  83F800            *   cmp eax , 0
00000043  7E0A              *   jng @C0004

Code: [Select]
00000000                        .if sdword ptr esi>ebx
00000000  3BF3              *   cmp sdword ptr esi, ebx
00000002  7E00     * jng @C0001

same as:
Code: [Select]
00000000                        .ifs esi > ebx
00000000  3BF3              *   cmp esi , ebx
00000002  7E00              *   jng @C0001
00000004                        .endif
00000004                    *   @C0001:

nidud

  • Member
  • *****
  • Posts: 1386
    • https://github.com/nidud/asmc
Re: Signed compare in HLL
« Reply #3 on: January 27, 2017, 06:58:50 AM »
HLL directives for pre-existing flag conditions added (same as Jxx)

Code: [Select]
.IFA - if Above
.IFB - if Below
.IFG - if Greater (signed)
.IFL - if Less (signed)
.IFO - if Overflow (signed)
.IFP - if Parity
.IFS - if Signed (signed)
.IFZ - if Zero
.IFNA - if Not Above
.IFNB - if Not Below
.IFNG - if Not Greater (signed)
.IFNL - if Not Less (signed)
.IFNO - if Not Overflow (signed)
.IFNP - if No Parity
.IFNS - if Not Signed (signed)
.IFNZ - if Not Zero

Note overlap of existing directive .IFB and .IFS:

Compare (returned) register from expression
Code: [Select]
.IFB <expression> - cmp al, 16/32/64
.IFW <expression> - cmp ax, 32/64
.IFD <expression> - cmp eax, 64

Signed compare
Code: [Select]
.IFS <expression> - cmp reg, 16/32/64
.IFSB <expression> - cmp al, 16/32/64
.IFSW <expression> - cmp ax, 32/64
.IFSD <expression> - cmp eax, 64

Test case:

https://github.com/nidud/asmc/blob/master/source/asmc/regress/src/bin/ifx.asm
« Last Edit: January 31, 2017, 09:59:23 AM by nidud »

nidud

  • Member
  • *****
  • Posts: 1386
    • https://github.com/nidud/asmc
Re: Signed compare in HLL
« Reply #4 on: January 27, 2017, 08:58:24 AM »
« Last Edit: January 31, 2017, 10:02:06 AM by nidud »

jj2007

  • Member
  • *****
  • Posts: 7633
  • Assembler is fun ;-)
    • MasmBasic
Re: Signed compare in HLL
« Reply #5 on: January 27, 2017, 09:14:15 AM »
   .UNTILBE  - until Not Below or Equal

Do you mean until Not Below or Equal?

nidud

  • Member
  • *****
  • Posts: 1386
    • https://github.com/nidud/asmc
Re: Signed compare in HLL
« Reply #6 on: January 27, 2017, 10:51:44 AM »
added HLL directives for .WHILExx
« Last Edit: January 31, 2017, 10:04:00 AM by nidud »

nidud

  • Member
  • *****
  • Posts: 1386
    • https://github.com/nidud/asmc
Re: Signed compare in HLL
« Reply #7 on: January 31, 2017, 11:18:40 AM »
Reduced number of flags:

xxsubs Jxx
ANBECF=0 and ZF=0Above Not Below or Equal
BC/NAECF=1Below Carry | Not Above or Equal
GNLEZF=0 and SF=OFGreater Not Less or Equal (signed)
LNGESF != OFLess Not Greater or Equal (signed)
OOF=1Overflow (signed)
PPEPF=1Parity Parity Even
SSF=1Signed (signed)
ZEZF=1Zero Equal
NABECF=1 or ZF=1Not Above Not Below or Equal
NBNC/AECF=0Not Below Not Carry, Above or Equal
NGLEZF=1 or SF != OFNot Greater Less or Equal (signed)
NLGESF=OFNot Less Greater or Equal (signed)
NOOF=0Not Overflow (signed)
NPPOPF=0No Parity Parity Odd
NSSF=0Not Signed (signed)
NZNEZF=0Not Zero Not Equal
« Last Edit: March 11, 2017, 05:30:53 AM by nidud »

nidud

  • Member
  • *****
  • Posts: 1386
    • https://github.com/nidud/asmc
Return code size
« Reply #8 on: March 11, 2017, 05:34:53 AM »
Added type check on function calls used as argument

foo proto :byte, :word, :dword, :qword
bar proto :byte

Code: [Select]
foo(bar(al),0,0,0)
foo(0,bar(al),0,0)
foo(0,0,bar(al),0)
foo(0,0,0,bar(al))

00000018 *   invoke foo, al, 0, 0, 0
00000039 *   invoke foo, 0, ax, 0, 0
00000059 *   invoke foo, 0, 0, eax, 0
00000077 *   invoke foo, 0, 0, 0, rax
..
00000051 *   invoke foo, 0, 0, 0, edx::eax

nidud

  • Member
  • *****
  • Posts: 1386
    • https://github.com/nidud/asmc
Re: Signed compare in HLL
« Reply #9 on: July 30, 2017, 07:05:58 AM »
Added switch /pf – Preserve Flags
Added option epilogue:flags

This to prevent invoke and epilogue code to change the flags from function calls. This apply to C/SYSCALL and 64-bit where the stack is corrected by adding value to SP.

If the option is set ADD is replaced with LEA to preserve the flags.

Example:
Code: [Select]
_divnd proc uses esi edi ebx dividend:ptr, divisor:ptr, reminder:ptr, n:dword

local count

    mov esi,dividend
    mov edi,reminder
    mov ecx,n
    rep movsd
    xor eax,eax
    mov edi,dividend
    mov ecx,n
    rep stosd

    .repeat

        option epilogue:flags
        ;
        ; Preserve flags from function calls
        ;
        _cmpnd(divisor, dividend, n)
        .ifz
            mov edi,reminder
            mov ecx,n
            rep stosd
            .break
        .endif

        _cmpnd(divisor, reminder, n)
        .ifa
            ;
            ; divisor > dividend : reminder = dividend, quotient = 0
            ;
            .break
        .else
            .ifz
                ;
                ; divisor == dividend : reminder = 0, quotient = 1
                ;
                mov edi,reminder
                mov ecx,n
                rep stosd
                mov edi,dividend
                inc byte ptr [edi]
                .break
            .endif
        .endif