Rocksolid Light

Welcome to novaBBS (click a section below)

mail  files  register  nodelist  faq  login

Computers don't actually think. You just think they think. (We think.)


programming / comp.lang.asm.x86 / Re: shorter code to print a 16bit number in 8086

SubjectAuthor
* shorter code to print a 16bit number in 8086luser...@nospicedham.gmail.com
+* Re: shorter code to print a 16bit number in 8086Kerr-Mudd, John
|`- Re: shorter code to print a 16bit number in 8086Kerr-Mudd, John
+- Re: shorter code to print a 16bit number in 8086wolfgang kern
+* Re: shorter code to print a 16bit number in 8086R.Wieser
|`* Re: shorter code to print a 16bit number in 8086Kerr-Mudd, John
| `- Re: shorter code to print a 16bit number in 8086R.Wieser
+* Re: shorter code to print a 16bit number in 8086Rod Pemberton
|`- Re: shorter code to print a 16bit number in 8086Frank Kotler
`- Re: shorter code to print a 16bit number in 8086luser...@nospicedham.gmail.com

1
Subject: shorter code to print a 16bit number in 8086
From: luser...@nospicedham
Newsgroups: comp.lang.asm.x86
Organization: A noiseless patient Spider
Date: Fri, 30 Jul 2021 05:11 UTC
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: luser.dr...@nospicedham.gmail.com (luser...@nospicedham.gmail.com)
Newsgroups: comp.lang.asm.x86
Subject: shorter code to print a 16bit number in 8086
Date: Thu, 29 Jul 2021 22:11:00 -0700 (PDT)
Organization: A noiseless patient Spider
Lines: 54
Approved: fbkotler@myfairpoint.net - comp.lang.asm.x86 moderation team.
Message-ID: <e898dcb7-8ffb-4eac-8c6c-5d50c687745en@googlegroups.com>
Mime-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
Injection-Date: Fri, 30 Jul 2021 05:11:01 +0000
Injection-Info: reader02.eternal-september.org; posting-host="46ed6d4cce65151d6a09d03753f84bdd";
logging-data="12381"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/367sshVAh3/LlcXQGPDK5fmA7UgGTx8E="
User-Agent: G2/1.0
Cancel-Lock: sha1:sWwWjGvLptGmB22j1XU9aHYrc9Q=
View all headers
I wrote this machine code to trace the LIT word in my forth interpreter.
Is it possible to tighten up this code? It's trying to print a 16bit signed
integer (ignoring INT_MIN) left to right with no leading zeros.

This is assembly code, but I hope you'll forgive my ideosyncratic syntax.
The operands map left to right to the reg and reg/mem fields into the
mod-reg-reg/mem byte and the opcodes target the "to" form (direction
field = 1), eg. in "MOV(,R,BX,AX)", BX is the dest, AX is the source, the
R is needed to select register-to-register mode (the mod field). The empty
first argument is for tweaks to the opcode which could be F (clear the
direction field by subtracting 2) or BYTE (clear the word field by subtracting 1).

It tests each digit for zero where it jumps over the int 10h call except
the last digit.

It occurs to me that the DIV instruction has a mod field. So that means
the divisor could be register indirect, right? like through SI or BX, maybe?
Then it could probably be rolled up in a loop, right? Sorry if I'm jumping
the gun asking for help before exerting the requisite effort.

CODE(lit,  lit,  LODS, PUSH(AX)

#ifdef TRACE

                 , MOV(,R,BX,AX), OR(,R,BX,BX), JGE,7, MOVI(AX,0x0E00+'-'), INT(10), NEG(R,BX),

MOV(,R,AX,BX), XOR(,R,DX,DX), MOVI(CX,10000), DIV(R,CX),

   OR(,R,AX,AX), JZ,6,  MOVBI(AH,0x0E), ADDAL(48), INT(10),

MOV(,R,AX,DX), XOR(,R,DX,DX), MOVI(CX,1000), DIV(R,CX),

   OR(,R,AX,AX), JZ,6,  MOVBI(AH,0x0E), ADDAL(48), INT(10),

MOV(,R,AX,DX), MOVBI(CL,100), XOR(BYTE,R,CH,CH), BYTE+DIV(R,CL),

   MOV(BYTE,R,DL,AH),

   OR(BYTE,R,AL,AL), JZ,6,  MOVBI(AH,0x0E), ADDAL(48), INT(10),

MOV(BYTE,R,AL,DL), XOR(BYTE,R,AH,AH), MOVBI(CL,10), BYTE+DIV(R,CL),

   MOV(BYTE,R,DL,AH),

   OR(BYTE,R,AL,AL), JZ,6,  MOVBI(AH,0x0E), ADDAL(48), INT(10),

MOVBI(AH,0x0E), MOV(BYTE,R,AL,DL), ADDAL(48), INT(10),

   MOVI(AX,0x0E00+' '), INT(10)

#endif

)/**/



Subject: Re: shorter code to print a 16bit number in 8086
From: Kerr-Mudd, John
Newsgroups: comp.lang.asm.x86
Organization: Dis
Date: Fri, 30 Jul 2021 12:52 UTC
References: 1
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: adm...@nospicedham.127.0.0.1 (Kerr-Mudd, John)
Newsgroups: comp.lang.asm.x86
Subject: Re: shorter code to print a 16bit number in 8086
Date: Fri, 30 Jul 2021 13:52:44 +0100
Organization: Dis
Lines: 95
Approved: fbkotler@myfairpoint.net - comp.lang.asm.x86 moderation team.
Message-ID: <20210730135244.82cbef35a80b4776b05722e4@127.0.0.1>
References: <e898dcb7-8ffb-4eac-8c6c-5d50c687745en@googlegroups.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Injection-Info: reader02.eternal-september.org; posting-host="46ed6d4cce65151d6a09d03753f84bdd";
logging-data="23165"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19PEKf6W+VHg/COIXY2212FAMW/FFVFhSY="
Cancel-Lock: sha1:x0zhch3QePBAawgjz0nNsDNlL/o=
View all headers
On Thu, 29 Jul 2021 22:11:00 -0700 (PDT)
"luser...@nospicedham.gmail.com" <luser.droog@nospicedham.gmail.com> wrote:

I wrote this machine code to trace the LIT word in my forth interpreter.
Is it possible to tighten up this code? It's trying to print a 16bit signed
integer (ignoring INT_MIN) left to right with no leading zeros.

This is assembly code, but I hope you'll forgive my ideosyncratic syntax.
The operands map left to right to the reg and reg/mem fields into the
mod-reg-reg/mem byte and the opcodes target the "to" form (direction
field = 1), eg. in "MOV(,R,BX,AX)", BX is the dest, AX is the source, the
R is needed to select register-to-register mode (the mod field). The empty
first argument is for tweaks to the opcode which could be F (clear the
direction field by subtracting 2) or BYTE (clear the word field by subtracting 1).

It tests each digit for zero where it jumps over the int 10h call except
the last digit.

It occurs to me that the DIV instruction has a mod field. So that means
the divisor could be register indirect, right? like through SI or BX, maybe?
Then it could probably be rolled up in a loop, right? Sorry if I'm jumping
the gun asking for help before exerting the requisite effort.

CODE(lit,  lit,  LODS, PUSH(AX)

#ifdef TRACE

                 , MOV(,R,BX,AX), OR(,R,BX,BX), JGE,7, MOVI(AX,0x0E00+'-'), INT(10), NEG(R,BX),

MOV(,R,AX,BX), XOR(,R,DX,DX), MOVI(CX,10000), DIV(R,CX),

   OR(,R,AX,AX), JZ,6,  MOVBI(AH,0x0E), ADDAL(48), INT(10),

MOV(,R,AX,DX), XOR(,R,DX,DX), MOVI(CX,1000), DIV(R,CX),

   OR(,R,AX,AX), JZ,6,  MOVBI(AH,0x0E), ADDAL(48), INT(10),

MOV(,R,AX,DX), MOVBI(CL,100), XOR(BYTE,R,CH,CH), BYTE+DIV(R,CL),

   MOV(BYTE,R,DL,AH),

   OR(BYTE,R,AL,AL), JZ,6,  MOVBI(AH,0x0E), ADDAL(48), INT(10),

MOV(BYTE,R,AL,DL), XOR(BYTE,R,AH,AH), MOVBI(CL,10), BYTE+DIV(R,CL),

   MOV(BYTE,R,DL,AH),

   OR(BYTE,R,AL,AL), JZ,6,  MOVBI(AH,0x0E), ADDAL(48), INT(10),

MOVBI(AH,0x0E), MOV(BYTE,R,AL,DL), ADDAL(48), INT(10),

   MOVI(AX,0x0E00+' '), INT(10)

#endif

)/**/

I think I got the jist of it;

here's some std asm code from earlier, rejigged for int 0x10 - it requires 5 free stack positions.
uses ax,bx,cx,dx - 36 bytes

PrtNum: ; ax to con using int10 fn 0E: no leading spaces or zeros but show '-'
         test ax,ax          ; Is it positive?
         jge NotNeg
        push ax
         mov ax,0x0E00+'-'
         int 0x10            ; bios prtc
        pop ax
         neg ax              ; show as positive: hibit set only for 0x8000!#
NotNeg:
         mov bx,10           ; decimal
         xor cx,cx           ; Digit count (5 max)
NextDigit:
         inc cx              ; prt at least 1 digit (i.e. '0')
         xor dx,dx           ; clear prev, cant cwd for #8000
         div bx
        push dx              ; Remainder is the digit
         test ax,ax          ; Is it zero yet?
         jnz NextDigit
PutDigit:
        pop ax               ; get digit (000x)
         add ax,0x0E+'0'     ; digit to display value, prtfn in ah
         int 0x10            ; bios prtc
         loop PutDigit        
        






--
Bah, and indeed Humbug.



Subject: Re: shorter code to print a 16bit number in 8086
From: wolfgang kern
Newsgroups: comp.lang.asm.x86
Organization: Aioe.org NNTP Server
Date: Fri, 30 Jul 2021 12:53 UTC
References: 1
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: nowh...@nospicedham.never.at (wolfgang kern)
Newsgroups: comp.lang.asm.x86
Subject: Re: shorter code to print a 16bit number in 8086
Date: Fri, 30 Jul 2021 14:53:56 +0200
Organization: Aioe.org NNTP Server
Lines: 70
Approved: fbkotler@myfairpoint.net - comp.lang.asm.x86 moderation team.
Message-ID: <se0spl$1c7i$1@gioia.aioe.org>
References: <e898dcb7-8ffb-4eac-8c6c-5d50c687745en@googlegroups.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Info: reader02.eternal-september.org; posting-host="46ed6d4cce65151d6a09d03753f84bdd";
logging-data="23192"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19jC/fihON3dhvOk9oz4+ddvJSQ69safaA="
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:91.0) Gecko/20100101
Thunderbird/91.0
Cancel-Lock: sha1:KN+YQNPnJAatBitrXXOfmoO8YsE=
View all headers
On 30.07.2021 07:11, luser...@nospicedham.gmail.com wrote:
I wrote this machine code to trace the LIT word in my forth interpreter.
Is it possible to tighten up this code? It's trying to print a 16bit signed
integer (ignoring INT_MIN) left to right with no leading zeros.

I'm sure that thjis could be made much faster and shorter too :)

This is assembly code, but I hope you'll forgive my ideosyncratic syntax.
The operands map left to right to the reg and reg/mem fields into the
mod-reg-reg/mem byte and the opcodes target the "to" form (direction
field = 1), eg. in "MOV(,R,BX,AX)", BX is the dest, AX is the source, the
R is needed to select register-to-register mode (the mod field). The empty
first argument is for tweaks to the opcode which could be F (clear the
direction field by subtracting 2) or BYTE (clear the word field by subtracting 1).

It tests each digit for zero where it jumps over the int 10h call except
the last digit.

to speed it up you can use reciprocal MUL instead if DIV
tried to fall through instead of jump over ?
better would be a buffer and only a single write to screen.

It occurs to me that the DIV instruction has a mod field. So that means
the divisor could be register indirect, right? like through SI or BX, maybe?
Then it could probably be rolled up in a loop, right? Sorry if I'm jumping
the gun asking for help before exerting the requisite effort.

don't you use them already?  DIV(R,CX)


CODE(lit,  lit,  LODS, PUSH(AX)

#ifdef TRACE

                  , MOV(,R,BX,AX), OR(,R,BX,BX), JGE,7, MOVI(AX,0x0E00+'-'), INT(10), NEG(R,BX),

MOV(,R,AX,BX), XOR(,R,DX,DX), MOVI(CX,10000), DIV(R,CX),

   OR(,R,AX,AX), JZ,6,  MOVBI(AH,0x0E), ADDAL(48), INT(10),

MOV(,R,AX,DX), XOR(,R,DX,DX), MOVI(CX,1000), DIV(R,CX),

   OR(,R,AX,AX), JZ,6,  MOVBI(AH,0x0E), ADDAL(48), INT(10),

MOV(,R,AX,DX), MOVBI(CL,100), XOR(BYTE,R,CH,CH), BYTE+DIV(R,CL),

   MOV(BYTE,R,DL,AH),

   OR(BYTE,R,AL,AL), JZ,6,  MOVBI(AH,0x0E), ADDAL(48), INT(10),

MOV(BYTE,R,AL,DL), XOR(BYTE,R,AH,AH), MOVBI(CL,10), BYTE+DIV(R,CL),

   MOV(BYTE,R,DL,AH),

   OR(BYTE,R,AL,AL), JZ,6,  MOVBI(AH,0x0E), ADDAL(48), INT(10),

MOVBI(AH,0x0E), MOV(BYTE,R,AL,DL), ADDAL(48), INT(10),

   MOVI(AX,0x0E00+' '), INT(10)

#endif

I'm not familiar with this syntax, but I see many equal lines before the too many INT 10.

F7 F0 ...F7 F7  and F6 F7..F6 F7 are indeed DIV by reg
same for the IDIV groups  F7 F8...
__
wolfgang



Subject: Re: shorter code to print a 16bit number in 8086
From: R.Wieser
Newsgroups: comp.lang.asm.x86
Organization: Aioe.org NNTP Server
Date: Fri, 30 Jul 2021 15:26 UTC
References: 1
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: addr...@nospicedham.not.available (R.Wieser)
Newsgroups: comp.lang.asm.x86
Subject: Re: shorter code to print a 16bit number in 8086
Date: Fri, 30 Jul 2021 17:26:59 +0200
Organization: Aioe.org NNTP Server
Lines: 46
Approved: fbkotler@myfairpoint.net - comp.lang.asm.x86 moderation team.
Message-ID: <se15og$l8$1@gioia.aioe.org>
References: <e898dcb7-8ffb-4eac-8c6c-5d50c687745en@googlegroups.com>
Injection-Info: reader02.eternal-september.org; posting-host="46ed6d4cce65151d6a09d03753f84bdd";
logging-data="23452"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+Wmd7Irz6GYe4RGdWLcYBp/Q/YLTNFvOM="
Cancel-Lock: sha1:GcYVKsh5KNrIW8gz1C9ZAYS1nBE=
View all headers
luser,

It's trying to print a 16bit signed integer (ignoring INT_MIN)
left to right with no leading zeros.
....
It tests each digit for zero where it jumps over the int 10h call
except the last digit.

Those two do not match.   And as your code seem to be written according to
the second ...
Try printing the value 3002 (or something else with embedded zeroes) to see
what I mean.

Is it possible to tighten up this code?

I'm not sure what "tighten up" is ment to be read as.   Smaller ?   Faster ?
In the first case, how many bytes is it now ?

My own, erstwhile "trick" was, while doing the same as you (dividing by the
largest divisor first), to load a register with the divisor and than call a
small routine doing the division and printing.

But in the light of your "skip leading zeroes" you could do worse than to
look at what John posted, as that method automatically discards leading
zeroes - it simply stops as soon as the remainder becomes zero.  I'm not so
sure about if that "loop" at the end will work though, as the INT 0x10 could
easily trash cx..

It occurs to me that the DIV instruction has a mod field. So that
means the divisor could be register indirect, right? like through SI
or BX, maybe?

Yes, would work.  And that same list can than also be used to skip leading
zeroes.

Sorry if I'm jumping the gun asking for help before exerting the
requisite effort.

I can imagine that you ask, but I do not quite understand why you did not
test your own code first ...

Regards,
Rudy Wieser





Subject: Re: shorter code to print a 16bit number in 8086
From: Kerr-Mudd, John
Newsgroups: comp.lang.asm.x86
Organization: Dis
Date: Fri, 30 Jul 2021 15:45 UTC
References: 1 2
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: adm...@nospicedham.127.0.0.1 (Kerr-Mudd, John)
Newsgroups: comp.lang.asm.x86
Subject: Re: shorter code to print a 16bit number in 8086
Date: Fri, 30 Jul 2021 16:45:29 +0100
Organization: Dis
Lines: 63
Approved: fbkotler@myfairpoint.net - comp.lang.asm.x86 moderation team.
Message-ID: <20210730164529.2b5b9b1deccba3c67bdb0829@127.0.0.1>
References: <e898dcb7-8ffb-4eac-8c6c-5d50c687745en@googlegroups.com>
<20210730135244.82cbef35a80b4776b05722e4@127.0.0.1>
Mime-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Injection-Info: reader02.eternal-september.org; posting-host="46ed6d4cce65151d6a09d03753f84bdd";
logging-data="4466"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/vLx2/+sTl4oL1cN/jg9Qyxd6x6RMGjgg="
Cancel-Lock: sha1:gkGD0QW1z0OKqYczLtM07eaJsAI=
View all headers
On Fri, 30 Jul 2021 13:52:44 +0100
"Kerr-Mudd, John" <admin@nospicedham.127.0.0.1> wrote:

On Thu, 29 Jul 2021 22:11:00 -0700 (PDT)
"luser...@nospicedham.gmail.com" <luser.droog@nospicedham.gmail.com> wrote:

I wrote this machine code to trace the LIT word in my forth interpreter.
Is it possible to tighten up this code? It's trying to print a 16bit signed
integer (ignoring INT_MIN) left to right with no leading zeros.


[]

I think I got the jist of it;

here's some std asm code from earlier, rejigged for int 0x10 - it requires 5 free stack positions.
uses ax,bx,cx,dx - 36 bytes

; corrected version - 37


PrtNum: ; ax to con using int10 fn 0E: no leading spaces or zeros but show '-'
         test ax,ax          ; Is it positive?
         jge NotNeg
        push ax
         mov ax,0x0E00+'-'
         int 0x10            ; bios prtc
        pop ax
         neg ax              ; show as positive: hibit set only for 0x8000!#
NotNeg:
         mov bx,10           ; decimal
         xor cx,cx           ; Digit count (5 max)
NextDigit:
         inc cx              ; prt at least 1 digit (i.e. '0')
         xor dx,dx           ; clear prev, cant cwd for #8000
         div bx
        push dx              ; Remainder is the digit
         test ax,ax          ; Is it zero yet?
         jnz NextDigit
PutDigit:
        pop ax               ; get digit (000x)

         add ax,0x0E+'0'     ; digit to display value, prtfn in ah
I didn't test! Make that line:
           add ax,0x0E00+'0'   ; digit to display value, prtfn in ah

           int 0x10            ; bios prtc
         loop PutDigit        
        






--
Bah, and indeed Humbug.



--
Bah, and indeed Humbug.



Subject: Re: shorter code to print a 16bit number in 8086
From: Kerr-Mudd, John
Newsgroups: comp.lang.asm.x86
Organization: Dis
Date: Fri, 30 Jul 2021 18:55 UTC
References: 1 2
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: adm...@nospicedham.127.0.0.1 (Kerr-Mudd, John)
Newsgroups: comp.lang.asm.x86
Subject: Re: shorter code to print a 16bit number in 8086
Date: Fri, 30 Jul 2021 19:55:09 +0100
Organization: Dis
Lines: 56
Approved: fbkotler@myfairpoint.net - comp.lang.asm.x86 moderation team.
Message-ID: <20210730195509.4035d2b2394cdd2d65f44ec8@127.0.0.1>
References: <e898dcb7-8ffb-4eac-8c6c-5d50c687745en@googlegroups.com>
<se15og$l8$1@gioia.aioe.org>
Mime-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Injection-Info: reader02.eternal-september.org; posting-host="46ed6d4cce65151d6a09d03753f84bdd";
logging-data="16239"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18MQhv4RfXISD7hkdnsEaxldgfHdIehr+E="
Cancel-Lock: sha1:q1hRTGwGBe/AU86WX2vEcO/xuc4=
View all headers
On Fri, 30 Jul 2021 17:26:59 +0200
"R.Wieser" <address@nospicedham.not.available> wrote:

luser,

It's trying to print a 16bit signed integer (ignoring INT_MIN)
left to right with no leading zeros.
...
It tests each digit for zero where it jumps over the int 10h call
except the last digit.

Those two do not match.   And as your code seem to be written according to
the second ...
Try printing the value 3002 (or something else with embedded zeroes) to see
what I mean.

Is it possible to tighten up this code?

I'm not sure what "tighten up" is ment to be read as.   Smaller ?   Faster ?
In the first case, how many bytes is it now ?

My own, erstwhile "trick" was, while doing the same as you (dividing by the
largest divisor first), to load a register with the divisor and than call a
small routine doing the division and printing.

But in the light of your "skip leading zeroes" you could do worse than to
look at what John posted, as that method automatically discards leading
zeroes - it simply stops as soon as the remainder becomes zero.  I'm not so
sure about if that "loop" at the end will work though, as the INT 0x10 could
easily trash cx..

Seems to be OK on this "DOS" VDM under XP - but yes, the int 10 was put in for the OP - originally the code put to a buffer at di, with a single print (ah=9, Int 21) at the end.

It occurs to me that the DIV instruction has a mod field. So that
means the divisor could be register indirect, right? like through SI
or BX, maybe?

Yes, would work.  And that same list can than also be used to skip leading
zeroes.

Sorry if I'm jumping the gun asking for help before exerting the
requisite effort.

I can imagine that you ask, but I do not quite understand why you did not
test your own code first ...

Regards,
Rudy Wieser





--
Bah, and indeed Humbug.



Subject: Re: shorter code to print a 16bit number in 8086
From: R.Wieser
Newsgroups: comp.lang.asm.x86
Organization: Aioe.org NNTP Server
Date: Fri, 30 Jul 2021 19:23 UTC
References: 1 2
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: addr...@nospicedham.not.available (R.Wieser)
Newsgroups: comp.lang.asm.x86
Subject: Re: shorter code to print a 16bit number in 8086
Date: Fri, 30 Jul 2021 21:23:19 +0200
Organization: Aioe.org NNTP Server
Lines: 21
Approved: fbkotler@myfairpoint.net - comp.lang.asm.x86 moderation team.
Message-ID: <se1jjl$qm5$1@gioia.aioe.org>
References: <e898dcb7-8ffb-4eac-8c6c-5d50c687745en@googlegroups.com><se15og$l8$1@gioia.aioe.org> <20210730195509.4035d2b2394cdd2d65f44ec8@127.0.0.1>
Injection-Info: reader02.eternal-september.org; posting-host="46ed6d4cce65151d6a09d03753f84bdd";
logging-data="29023"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18FUfaTD29lgkGwLJBqb5etIPp9Iv6JnhY="
Cancel-Lock: sha1:2k/MkgaFQKQ1jsWx8Zdijnuyaqs=
View all headers
John,

sure about if that "loop" at the end will work though, as the INT 0x10
could easily trash cx..

Seems to be OK on this "DOS" VDM under XP - but yes, the int 10 was
put in for the OP - originally the code put to a buffer at di, with a
single
print (ah=9, Int 21) at the end.

Yes, it also works here (XP Pro sp3).  But its not something I will bet my
life on - because the specs say that a(ny) function call (including INTs)
may trash AX thru DX at will.

I know its hard to take, but the extra two bytes for a push/pop cx around
that last INT 0x10 are really needed. :-)

Regards,
Rudy Wieser




Subject: Re: shorter code to print a 16bit number in 8086
From: Rod Pemberton
Newsgroups: comp.lang.asm.x86
Organization: Aioe.org NNTP Server
Date: Fri, 30 Jul 2021 10:01 UTC
References: 1
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: noem...@basdxcqvbe.com (Rod Pemberton)
Newsgroups: comp.lang.asm.x86
Subject: Re: shorter code to print a 16bit number in 8086
Date: Fri, 30 Jul 2021 05:01:13 -0500
Organization: Aioe.org NNTP Server
Lines: 66
Approved: fbkotler@myfairpoint.net - comp.lang.asm.x86 moderation team.
Message-ID: <se0f27$ji1$1@gioia.aioe.org>
References: <e898dcb7-8ffb-4eac-8c6c-5d50c687745en@googlegroups.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Injection-Info: reader02.eternal-september.org; posting-host="3a95024023917270cbe8dee77bd540ff";
logging-data="3768"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19mSxXO/QL0F9eSGA+phpa1xFKMzY2MTKQ="
Cancel-Lock: sha1:wR/XS5f+sn77w/zgvozS6YgnrOQ=
View all headers
On Thu, 29 Jul 2021 22:11:00 -0700 (PDT)
"luser...@nospicedham.gmail.com" <luser.droog@nospicedham.gmail.com>
wrote:


Sorry Frank, the first part of this may be a off-topic,
but I haven't been reading or posting to comp.lang.forth
in a while.  So, I can understand if the OP posts here
with some Forth-ish assembly ...

I wrote this machine code to trace the LIT word in
my forth interpreter.

LIT is usually very simple and just stores an integer from
the interpreter's input stream into the current Forth word.


In C, my LIT primitive - the low-level function which goes
with the LIT dictionary entry - is:

void lit__(void)
{
  push((cell_t)*ip);
  ip++;
}

This dereferences/fetches what's at the Forth interpreter's
instruction pointer IP, stores that value on the parameter/data
stack, and then increments the IP.


I have LIT in the initial dictionary in C code (which I
use instead of assembly), because LIT is needed prior to
loading a high-level Forth dictionary.  LIT is not a
standardized Forth word (subroutine).


You should be able to construct a LIT from your COMPILE
definition.  E.g., just drop the , (comma) or equivalent
Forth word like COMPILE, from the end of the definition:

: COMPILE R> DUP CELL+ >R @ , ;
: LIT R> DUP CELL+ >R @ ;

For my personal Forth interpreter, the LIT is high-level
version of LIT equivalent to the low-level C code above.

I.e., the R> (r-from) captures the interpreter's saved IP,
DUPlicates the IP, increments one copy of the IP to skip
over the value, places the adjusted IP onto the return stack
via >R (to-r), fetches the value from the original IP onto
the parameter/data stack.  That is the LIT value.

Is it possible to tighten up this code? It's trying to
print a 16bit signed integer (ignoring INT_MIN) left to
right with no leading zeros.

Well, I really didn't look at the Forth-ish assembly,
but my suggestion to make your life easier would be
to print the decimal(?) "16bit signed integer" instead
in hexadecimal as a "16bit UN-signed integer".


--
....



Subject: Re: shorter code to print a 16bit number in 8086
From: Frank Kotler
Newsgroups: comp.lang.asm.x86
Organization: Aioe.org NNTP Server
Date: Fri, 30 Jul 2021 22:39 UTC
References: 1 2
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: fbkot...@nospicedham.myfairpoint.net (Frank Kotler)
Newsgroups: comp.lang.asm.x86
Subject: Re: shorter code to print a 16bit number in 8086
Date: Fri, 30 Jul 2021 18:39:39 -0400
Organization: Aioe.org NNTP Server
Lines: 17
Approved: fbkotler@myfairpoint.net - comp.lang.asm.x86 moderation team.
Message-ID: <se1vna$1kqk$1@gioia.aioe.org>
References: <e898dcb7-8ffb-4eac-8c6c-5d50c687745en@googlegroups.com>
<se0f27$ji1$1@gioia.aioe.org>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Info: reader02.eternal-september.org; posting-host="3a95024023917270cbe8dee77bd540ff";
logging-data="9447"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX186u5etGBTXrdI3x1ZF0JqMtNHGOwzVMis="
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101
Thunderbird/52.5.2
Cancel-Lock: sha1:0xxUf6LOCFBKVcnbgOqTQQ5lRGE=
View all headers
On 07/30/2021 06:01 AM, Rod Pemberton wrote:
On Thu, 29 Jul 2021 22:11:00 -0700 (PDT)
"luser...@nospicedham.gmail.com" <luser.droog@nospicedham.gmail.com>
wrote:


Sorry Frank,
Sorry Rod for the delay in posting = you keep changing your address so you're not in the "whitelist" (name changed soon to "karenlist" so it's not racist)
Try to stay on topic everyone... but it's bot as if we're swamped with traffic...

Best,
Frank
[moderator]



Subject: Re: shorter code to print a 16bit number in 8086
From: luser...@nospicedham
Newsgroups: comp.lang.asm.x86
Organization: A noiseless patient Spider
Date: Sat, 7 Aug 2021 05:04 UTC
References: 1
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: luser.dr...@nospicedham.gmail.com (luser...@nospicedham.gmail.com)
Newsgroups: comp.lang.asm.x86
Subject: Re: shorter code to print a 16bit number in 8086
Date: Fri, 6 Aug 2021 22:04:30 -0700 (PDT)
Organization: A noiseless patient Spider
Lines: 117
Approved: fbkotler@myfairpoint.net - comp.lang.asm.x86 moderation team.
Message-ID: <db2e535b-8d44-4fe7-92b4-5786fc608983n@googlegroups.com>
References: <e898dcb7-8ffb-4eac-8c6c-5d50c687745en@googlegroups.com>
Mime-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
Injection-Date: Sat, 07 Aug 2021 05:04:31 +0000
Injection-Info: reader02.eternal-september.org; posting-host="b8810090f94ae0d84cf5e44f2730ec02";
logging-data="13636"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/gxoOdwIt5falghKSxf4eoooqAjZ1upYg="
User-Agent: G2/1.0
Cancel-Lock: sha1:XbScmoln2gXPSo20DGCM1mtEj4U=
View all headers
On Friday, July 30, 2021 at 12:13:00 AM UTC-5, luser...@nospicedham.gmail.com wrote:
I wrote this machine code to trace the LIT word in my forth interpreter.
Is it possible to tighten up this code? It's trying to print a 16bit signed
integer (ignoring INT_MIN) left to right with no leading zeros.

This is assembly code, but I hope you'll forgive my ideosyncratic syntax.
The operands map left to right to the reg and reg/mem fields into the
mod-reg-reg/mem byte and the opcodes target the "to" form (direction
field = 1), eg. in "MOV(,R,BX,AX)", BX is the dest, AX is the source, the
R is needed to select register-to-register mode (the mod field). The empty
first argument is for tweaks to the opcode which could be F (clear the
direction field by subtracting 2) or BYTE (clear the word field by subtracting 1).

It tests each digit for zero where it jumps over the int 10h call except
the last digit.

It occurs to me that the DIV instruction has a mod field. So that means
the divisor could be register indirect, right? like through SI or BX, maybe?
Then it could probably be rolled up in a loop, right? Sorry if I'm jumping
the gun asking for help before exerting the requisite effort.


Thanks for the help, everyone! Thanks to Rudy for pointing out that my
algorithm was malformed. I had tested it (sort of, I ran it and saw that
there was output), but I didn't check it against known values and so
didn't see the problem of suppressing inner zeros. (the numbers it
printed did appear weird, but I didn't properly consider and valuate
that clue).

John's code is so sweet and simple, I am envious of the ability to write
in such a way. I translated it to my syntax and then tried a few of the
variations alluded to earlier, like using BX to point to a table of divisors.
But I haven't actually implemented the LOOP instruction in the emulator
and the syntax I have for using labels in machine code hasn't been
incorporated into the emulator at all yet. So I haven't tested any of the
following code except to run it through CPP to check that macro expansion
works.

First I just translated John's code to my syntax (now with labels) and
lo and behold, it's super short and sweet. Exactly what I asked for.

CODE(lit,    (LIT, LODS, PUSH(AX))
#ifdef TRACE
           , (PrtNum,    TEST(R,AX,AX), JGE, NotNeg-_, \
                         PUSH(AX), MOVAX(0xE00+'-'), INT(10), POP(AX), NEG(R,AX)),
             (NotNeg,    MOVBX(10), XOR(,R,CX,CX)),
             (NextDigit, INC(CX), XOR(DX,DX), DIV(BX), PUSH(DX), TEST(AX,AX), JNZ, NextDigit-_),
             (PutDigit,  POP(AX), ADDAX(0xE00+'0'), INT(10), LOOP, PutDigit-_)
#endif
)

First I tried doing it with a table of divisors and unrolled code to divide by each
word in the table.

CODE(lit,    (LIT,      LODS, PUSH(AX))
#ifdef TRACE
           , (stub,     sJMP, CODE-_),
             (divisors, DW(10000), DW(1000), DW(100), DW(10)),
             (CODE,     MOVBX(divisors), XOR(,R,DX,DX),
                        DIV(Z,BX_), ADDAX(0xE00+'0'), INT(10)),
             (L1,       MOV(,R,AX,DX), DIV(B,BX_),2, ADDAX(0xE000+'0'), INT(10),
                        MOV(,R,AX,DX), DIV(B,BX_),4, ADDAX(0xE000+'0'), INT(10)),
             (L2,       MOV(,R,AX,DX), DIV(B,BX_),6, ADDAX(0xE000+'0'), INT(10),
                MOD(,R,AX,DX), ADDAX(0xE00+'0'), INT(10))
#endif
)

Which is longer, uglier, replete with repetition.

Then I tried doing it with a table of divisors and a loop to run through left-to-right.

CODE(lit,    (LIT,      LODS, PUSH(AX))
#ifdef TRACE
    , (tracelit, MOVBX(divisors), XOR(,R,DX,DX), MOVCX(5)),
      (digit,    DIV(Z,BX_), ADDAX(0xE00+'0'), INT(10),
                 MOV(,R,AX,DX), ADDI(BX,2), LOOP, digit-_,
                 NEXT)
      (divisors, DW(10000), DW(1000), DW(100), DW(10), DW(1)),
#endif
)

where NEXT is a macro for jumping to the next Forth word, pointed to by SI.
That's pretty short, but it treats all numbers as unsigned and makes
no attempt to suppress leading zeros.

Then I tried without using a table and calling a procedure for each digit.

CODE(lit,    (LIT,      LODS, PUSH(AX))
#ifdef TRACE
    , (tracelit, XOR(,R,DX,DX), MOVCX(5),
                 TEST(R,AX,AX), JGE,notneg,
                 MOVI(AX,0xE00+'-'), INT(10), NEG(R,AX), JNO, notneg,
                 INC(R,DX)),
      (notneg,   MOVI(BX,10000), DIV(R,BX), CALL, print,
                 MOVI(BX,1000), MOV(,R,AX,DX), DIV(R,BX), CALL, print,
                 MOVI(BX,100), MOV(,R,AX,DX), DIV(R,BX), CALL, print,
                 MOVI(BX,10), MOV(,R,AX,DX), DIV(R,BX), CALL, print,
                 MOV(,R,AX,DX), CALL, print,
                 NEXT),
      (print,    ADDAX(0xE00'0'), INT(10), RET)
#endif
)

It's pretty cool that adding labels also lets me have local procedures,
but I feel like the call instruction vs, the ADD and INT instructions
doesn't really save much and is slower and longer on the screen.
But maybe all that just means that I should be using a DOS string
printing function instead of a character printing function.

And also, Rod was right and this whole effort was a wholy
unnecessary X/Y problem. And if I just add a high-level LIT word,
then I can call U. to print the number be done with this snipe hunt.

On a side note, I stumbled across the source on github for DOS 1.25
and 2.0 and I'm browsing ASM.ASM from 1.25 to get ideas about how to
make an assembler with a more common syntax.



1
rocksolid light 0.7.2
clearneti2ptor