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!!!
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.
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
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.
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
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
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 .
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. :)
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)
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?
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.
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
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.