flat assembler
Message board for the users of flat assembler.
![]() Goto page 1, 2 Next |
Author |
|
windwakr 22 Jul 2008, 21:09
How would I go about doing binary to decimal to display on screen? I'm very confused about this. All things I see to do bin to dec would just do bin to hex in computers....ugh...like http://en.wikipedia.org/wiki/Binary_numeral_system#Decimal that. I need to convert to string somehow. But how would I figure out how to do that?
|
|||
![]() |
|
windwakr 22 Jul 2008, 23:25
Would something like THIS be faster? How would I implement it? With BCD, it would be much easier to display.
|
|||
![]() |
|
LocoDelAssembly 22 Jul 2008, 23:32
mmmh, note that CPUs are not as flexible as FPGAs are
![]() |
|||
![]() |
|
windwakr 22 Jul 2008, 23:51
I found this neat c++ code that does what I want, very small to implement. Works up to 99, To do over that, you would need to modify it.
unsigned char chartobcd(unsigned char n) { return ((n / 10) << 4) | (n % 10); } In asm, its simple. (the 'hexword' routine was written by rugxulo and displays a hex number to screen) Code: org 100h start: mov ax,1100011b ;99 in decimal mov bl,10 ;10 for division div bl ;divide. the quotient is in al, the remainder is in ah mov dl,ah ;save remainder shl ax,4 ;shift quotient to ah or al,dl ;put remainder in al call hexword ;call routine to display it key: in al,60h dec al jnz key ret hexword: mov cx,2 .begin: push cx mov cl,4 rol al,cl pop cx push ax and al,0Fh cmp al,10 sbb al,69h das int 29h pop ax loop .begin .ret: ret Why wont a rol ax,4 work to replace the saving and putting back of the remainder?? |
|||
![]() |
|
DOS386 23 Jul 2008, 02:39
> How would I go about doing binary to decimal to display on screen?
Download an example ![]() > Why wont a rol ax,4 work to replace the saving and putting back of the remainder?? ROL AX, 1 - 8086 compatible ROL AX, CL - 8086 compatible ROL AX, 4 - not 8086 compatible _________________ Bug Nr.: 12345 Title: Hello World program compiles to 100 KB !!! Status: Closed: NOT a Bug |
|||
![]() |
|
revolution 23 Jul 2008, 04:24
DOS386 wrote: ROL AX, 1 - 8086 compatible |
|||
![]() |
|
DOS386 23 Jul 2008, 04:53
> but why is that relevant?
1st the guy asked 2nd one can see such code and get irritated about it 3rd one can code 8086-compatible, just for the heck ![]() |
|||
![]() |
|
windwakr 23 Jul 2008, 21:28
Ok, I found one written by thimis thats only 24 bytes and works with up to FFFFh
It's in This Thread. Code: dispnum: mov cx,10 ; print ax number in decimal dn: xor dx,dx div cx push dx or ax,ax jz @f call dn @@: pop dx add dl,30h mov ah,2 int 21h ret It recursively calls itself until all numbers are done. (It's somewhat confusing to me, but I think I understand it.) |
|||
![]() |
|
windwakr 24 Jul 2008, 20:17
I'm having trouble modifying thimis' code to print ','s
The modified code only prints '65,' and then halts. My code is in between ;;new blocks fch is comma minus 30h Code: org 100h mov ax,03h int 10h mov ax,65535 call dispnum key: in al,60h dec al jnz key ret dispnum: mov cx,10 ; print ax number in decimal ;;new mov bx,3 ;;new dn: xor dx,dx div cx push dx ;;new dec bx jnz @f mov bx,3 push 0fch @@: ;;new or ax,ax jz @f call dn @@: pop dx add dl,30h mov ah,2 int 21h ret I'm experimenting with using colors to make certain words stand out more. Mainly, names in red |
|||
![]() |
|
sinsi 25 Jul 2008, 00:12
Because that code is recursive, the extra "push 0fch" is mucking up the return address - in the case of 65535 it actually returns to address 0005, which crashes. Here's some old code I used to use (before I found something 100x faster)
Code: number_to_dec: pusha mov si,10 sub bx,bx .next: sub dx,dx div si push dx inc bh test ax,ax jz .reverse inc bl cmp bl,3 jnz .next push ','-'0' inc bh sub bl,bl jmp .next .reverse: pop ax add al,'0' call printchar dec bh jnz .reverse popa ret It uses BH to keep track of pushes and BL to count when a comma is needed. Start using EAX,EDX etc and it does 32-bit numbers too. |
|||
![]() |
|
windwakr 25 Jul 2008, 02:05
Ok, I sat down for 10min and rewrote thimis' code.
IT WORKS. I don't entirely understand why bx has to be set to 4, but it works and thats all that matters Code: org 100h mov ax,03h int 10h mov ax,0FFFFh call dispnum key: in al,60h dec al jnz key ret dispnum: mov cx,10 ;for dividing mov bx,4 ;for comma count dn: xor dx,dx ;zero out dx dec bx ;decrease bx jnz @f ;if bx is zero that means comma has been found mov bx,4 ;put bx back to 4 push 0fch ;push comma-30h jmp @123 ;jmp to call(we dont call here for many reasons) @@: div cx ;if not, divide by 10 push dx ;push remainder or ax,ax ;test for zero jz @f ;if it is go to displayer @123: call dn ;call whole routine again @@: pop dx ;pop first number off stack add dl,30h ;make it ascii mov ah,2 ;function 2 is display character int 21h ;display it ret ;basically a loop and then return to caller EDIT: When changed to use eax with numbers up to billions, It still works right. yay ![]() (the div cx needs to be changed to ecx too) EDIT 2:tried commenting the dispnum routine EDFED: I kinda ignored your post, sorry. But I saw 32 bits and weird divs and went "WOAH" and just kinda skipped over it. I dont like using 32bit for some reason. Plus, your code just looked a little complex. |
|||
![]() |
|
neville 25 Jul 2008, 04:00
I wrote a routine for FAMOS which displays a 32-bit number in any base you choose (usually hex or decimal, but could be binary ou up to base 36 using letters A-Z), with all leading zeros suppressed so you can also control the maximum no of digits displayed. Would easily convert to DOS if you're intereted.
|
|||
![]() |
|
windwakr 25 Jul 2008, 04:30
Nah, the routine I have is good enough
|
|||
![]() |
|
neville 25 Jul 2008, 04:40
thanks anyway, for the opportunity to give it to you.
|
|||
![]() |
|
Shahada 25 Jul 2008, 10:07
@neville
I'm interested to see the routine. Where can I find the source code for FAMOS? Or it is not open source? What lincense it has? |
|||
![]() |
|
DOS386 26 Jul 2008, 06:28
Shahada wrote: interested to see the routine. ... Or it is not open source? See above, my example is open source. ![]() _________________ Bug Nr.: 12345 Title: Hello World program compiles to 100 KB !!! Status: Closed: NOT a Bug |
|||
![]() |
|
Shahada 26 Jul 2008, 07:10
DOS386 wrote: See above, my example is open source. I saw yor example, but it is better to have more examples, so I want to see neville's way of doing it. Do you know more detailes about FAMOS? |
|||
![]() |
|
rugxulo 27 Jul 2008, 02:28
You can do it all without any slow DIVs at all. (In fact, you can supposedly do the whole conversion faster than a single DIV opcode.) See Terje's method (386+). However, it has leading zeros and no commas.
If you want 8086 code with commas that still works with a 32-bit number, try my bin2dec routine (although it puts the entire ASCIIZ result in a buffer backwards, so you have to either reverse it before output or output in reverse). Unlike the first method, it's not optimized for speed. EDIT: "div cx" (or any word register / memory value) always uses DX:AX (which is a 32-bit number). "div cl" is faster, and that's all you really need if you only want a 16-bit number (e.g. value in AX). So no, you don't need 386+ to do 32-bit arithmetic. Heck, you can even do 64-bit numbers too (on an 8086!). See here ("bignum"). Last edited by rugxulo on 27 Jul 2008, 02:51; edited 2 times in total |
|||
![]() |
|
rugxulo 27 Jul 2008, 02:41
windwakr wrote: I found this neat c++ code that does what I want, very small to implement. Works up to 99, To do over that, you would need to modify it. BTW, if you're curious, here's what GCC 4.3.0 outputs for that (no MULs or DIVs!): Code: _chartobcd: mov cl, BYTE PTR [esp+4] xor eax, eax mov al, cl lea edx, [eax+eax*4] lea edx, [eax+edx*8] lea edx, [edx+edx*4] shr dx, 8 shr dl, 3 mov al, dl sal eax, 4 lea edx, [edx+edx*4] add edx, edx sub cl, dl or eax, ecx ret |
|||
![]() |
|
Goto page 1, 2 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.