How to convert program to work with 32bit numbers ?

Started by umen, August 26, 2005, 08:39:16 PM

Previous topic - Next topic

umen

Hello
i have this simple program that do square calculation but with 16bit numbers
how can i take this program and make it work with 32 bit numbers ? so i can calculat numbers like :
1000000 and so on ?
any help and source codes or links will halp me allot
here is my code :
-------------------------------------------------------------------------------------------------------
LF   EQU  0AH
CR   EQU  0DH


DSEG SEGMENT
DSEG ENDS
SSEG SEGMENT STACK
DW  100H DUP(?)
SSEG ENDS
CSEG SEGMENT
  ASSUME  CS:CSEG,DS:DSEG,SS:SSEG
BEGIN:
; uses di, bx, cx, dx
;
; square root of AX via Newton-Raphson iteration.
    mov di,ax
    mov ax,13
start_loop:
    mov bx,ax
    xor dx,dx
    mov ax,di
    div bx
    add ax,bx
    shr ax,1
    mov cx,ax
    sub cx,bx
    cmp cx,2
    je  start_loop

CALL PRINT_AX_2



READCHAR: MOV  AH,1
        INT    21H
        RET

PRINTCHAR:MOV  AH,2
        INT  21H
        RET

PRINT_NEWLINE: MOV  DL,CR
       CALL  PRINTCHAR
       MOV   DL,LF
       CALL  PRINTCHAR
       RET
;***************************************************************
print_ax_1      proc near
         
      MOV     CL,4
      MOV     DL,AL
      SHR     DL,CL
      CALL    PRINT_AX
      MOV     DL,AL
     
      AND     DL,0FH
      CALL    PRINT_AX
      MOV     DL,AH
      SHR     DL,CL
      CALL    PRINT_AX
      MOV     DL,AH
 
      AND     DL,0FH
      CALL    PRINT_AX
      ret
print_ax_1      endp

print_ax_2     proc near
      MOV     CL,4
      MOV     DL,AH
      SHR     DL,CL
      CALL    PRINT_AX
      MOV     DL,AH
      AND     DL,0FH
      CALL    PRINT_AX
      MOV     DL,AL
      SHR     DL,CL
      CALL    PRINT_AX
      MOV     DL,AL
      AND     DL,0FH
      CALL    PRINT_AX
      ret
print_ax_2      endp

PRINT_AX      PROC    NEAR
      PUSH    AX
      ADD     DL,30H
      CMP     DL,'9'
      JBE     OK
      ADD     DL,7
OK:           MOV     AH,2
      INT     21H
      POP     AX
      RET
PRINT_AX        ENDP

CSEG ENDS
END BEGIN
---------------------------------------------------------------------------------------------------------
Thanks allot!!!

MichaelW

Add a .386 or higher processor directive. You will then be able to utilize 32-bit instructions and registers, but note that this will not change the address size, so you will still have a 16-bit limit for segments and offset addresses.

eschew obfuscation

umen

Hello and thanks for your replay , but the problem i to newbe to masm to understand what you suggest
basically i like the program to except big numbers and perform
on them the Newton square root .
so as u see i can't implant your suggestion
can someone please help me whith source code on the web or something ?
Thanks 

hutch--

umen,

To do this stuff well with far more power, ease and speed you need to go to 32 bit masm code and at a console level this is very easy code to write with the macro system in place for masm32.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

umen

well my propose is to learn basic/classic  masm but it is haed to believe that there is no why to deal with
large numbers in 16 bit masm .
is there any source/link on the web that contains examples source codes?
thanks for the hellpers

hutch--

The obvious thing that will cause you problems in 16 bit is the range of a WORD value which is 64k. When you use 32 bit the range is 4 gig and its easy to do. You also have better instructions from FP to SSE(2) if you have a late enough version of ML (6.15 or later) so all up, unless you specifically need to write 16 bit code for legacy applicaions, 32 bit code wins all round. More instructions, 4 gig range, much faster and less restrictions.

Just let us know if you want to try out 32 bit in MASM, its a ton of fun.  :green
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

umen

Hello and tnx allot for the fast reply
confused again ..
cant i use 32 bit numbers ( big numbers ) with 2 registers ? in 16 masm ?
yes i like to get square root of number to understand and learn from it.
if i just could find working code example of such thing , im sure i could learn allot .

Mark Jones

Quote from: umen on August 29, 2005, 07:22:02 PM
cant i use 32 bit numbers ( big numbers ) with 2 registers ? in 16 masm ?
yes i like to get square root of number to understand and learn from it.
if i just could find working code example of such thing , im sure i could learn allot .

Hi umen. This is more a question than advice, but can you write the code in C and compile it to a 16-bit file, creating assembler output? Then you could study that output and see how the compiler did it. :)
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

P1

umen,

Most of your posts look like homework questions ( This one is a standard for Math. ).  Only an instructor, would restrict the use to 16bit and require the conversion of the code.  Otherwise, if it was anything else than homework, your free to use what ever works.  Including the FPU, And perform modern programming.

Is this homework from a course of study?

Regards,  P1  :8)

umen

P1: Hello , this is not homework this is me trying to learn masm for old dos computers , and learning curve as I found out in the last few day are very hard
im used to learn from source files , so I was thinking if I could see how it done I could learn from it .

Mark Jones : good idea .. how can it be done technically?

hutch--

umen,

32 bit numbers used to be handled in the DX:AX register pair but it was never easy code to write. If you can get your hands on an old 16 bit C library you may get a set of functions that will do it for you or at worst, if you disassemble the code afte you have built it, you should be able to see how is done.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

gabor

#11
Hi Uman!

I read through the topic and I can give you this advice:

Yes, it is possible to do 32bit calculations in 16bit code. For division and multilplication the dx:ax pair is used, for addition and subtraction you have to handle the overflow by using the carry flag. Like this:

;
; add 123A400h and 0E008100h
;
; first operand in dx:ax
mov  dx,0123h
mov  ax,0A400h
; add low word first to get overflow in carry
add  ax,8100h   ; ax = 02500h and carry is set
adc  dx,0E00h   ; dx = 0F23h and add carry to dx
; result is in dx:ax

You can see, if the result of the addition was bigger than 64k, it won't fit into ax (16bit). The carry is set and is added to dx (high word of result). In the example 123A400h+0E008100h = 0F242500h; dx = 0F24h and ax = 2500h.

Subtraction is similiar.

; first operand
mov  dx,0123h
mov  ax,8100h
; sub low word first to get overflow (or is it in this case underflow? :) )
sub  ax,0A400h  ; ax = -2300h (DD00h), carry is set
sbc  dx,0E00h   ; dx = -0CDDh (F323h) and sub carry
; result is in dx:ax again

1238100h-0E00A400h = -CDD2300 (0F322DD00h); dx = 0F322h, ax =DD00h.

I am not 100% certain about the sbc instruction, but it should work this way...

BUT!! As another post suggested (maybe Hutch's post) you should change to masm32 or other 32 bit enviroment. Using 32 bit numbers is just one advantage. I started asm with 16 bit coding several years ago (actually I started coding in asm on C64...), but now I use 32 bit coding. It is easier, compacter and more up-to-date. Nowdays asm coding seems to be a fossil, many think of it as a dinosaur (those who think that JAVA .NET and other high level stuff are driven by small sprites and dwarves, they don't know about instruction sets, and addressing...), so we do have to keep a bit up. But we'll survive! :))

Greets, Gábor


MichaelW

#12
umem,

As has been stated, you can write code to handle 32-bit numbers with 16-bit instructions and 16-bit registers. But assuming your system has a 386 or later processor, it would be much easier to use 32-bit instructions and 32-bit registers. You can readily do this in a 16-bit program, and most of what you would learn from the experience would be applicable to 32-bit programs. You can enable the assembly of 32-bit instructions by placing a .386 or higher processor directive in your code at some location after the segment definitions and before the first statement that uses a 32-bit instruction or register. The reason for placing the processor directive after the segment definitions is that you did not specify the segment word size in the definitions, and when MASM encounters the processor directive it switches from assuming 16-bit segments to assuming 32-bit segments.

To clarify my statement regarding the address size, the primary difference between a 16-bit program and a 32-bit program is in the size of the addresses the program uses. A 32-bit program uses 32-bit addresses, so the maximum segment size is 100000000h bytes and the maximum offset address is 0FFFFFFFFh. A 16-bit program uses 16-bit addresses, so the maximum segment size is 10000h bytes and the maximum offset address is 0FFFFh. So basically, you can use 32-bit numbers in a 16-bit program, but you cannot use them as addresses.

The code you posted contains two significant problems. The first is the lack of any code to load the segment address of the data segment into DS. Because the program loader sets DS (and ES) to the segment address of the Program Segment Prefix (PSP), the program cannot access data in the data segment (without using a segment override) until it has loaded the segment address of the data segment into DS. The second problem is that the program is not terminating properly. After the call to PRINT_AX_2 returns the program waits for a key press, and then it does a near return using whatever happens to be on the stack for a return address. A near return is a valid method of terminating a COM program, but not an EXE.

For information on segment structure, initializing DS, etc, see the MASM 6.x manuals available here:

http://webster.cs.ucr.edu/Page_TechDocs/index.html

For information on the DOS and BIOS interrupts see Ralf Brown's Interrupt List:

An HTML version is here:

http://www.ctyme.com/rbrown.htm

And the download version here:

http://www-2.cs.cmu.edu/~ralf/files.html

The function of choice for terminating a DOS program (COM or EXE) is Interrupt 21h Function 4Ch.
eschew obfuscation