Matrix in assembly mxn dimension in emu 8086

Started by zemzi, January 05, 2012, 01:34:43 PM

Previous topic - Next topic

zemzi

I made a code in assembly 8086. I load matrix (array) in memory with dimension 3x3. but this code works just for this dimension of matrix 3x3. Could someone give me an idea how could i make it to work with dimension m x n? the array is loaded in memory and at the end just print the result, another array.


; multi-segment executable file template.

data segment
matrix db 1, 2, 3, 4, 5, 6, 7, 8, 9 ; load matrix in memory

ends

stack segment
dw 128 dup(0)
ends

code segment
start:
; set segment registers:
mov ax, data
mov ds, ax
mov es, ax



mov bx, matrix ; move matrix to offset bx
mov ch, 3
mov cl, 0


COLUMNAHEAD:

mov dl, [bx] ; get the first element of matrix in dl
add dl, 30h ; add to show number
mov ah, 02h
int 21h ; print first number
inc cl

cmp cl, ch ; compare if the counter is at the end of column


jge ROWAHEAD ; if greater go to row
add bx, 3 ; if not inc offset for 3
jmp COLUMNAHEAD





ROWAHEAD:
inc cl ; 1 element of roe
inc bx ; inc offset for one place
mov dl, [bx] ; get the number in dl
add dl, 30h ; convert to number
mov ah, 02h
int 21h ; print the number

cmp cl, 5
je COLUMNAHEAD
jne ROWAHEAD


COLUMNBACK:
inc cl
sub bx, 3
mov dl, [bx]
add dl, 30h
mov ah, 02h
int 21h
cmp cl, 7
jne COLUMNBACK
je ROWBACK

ROWBACK:
dec bx
mov dl, [bx]
add dl, 30h
mov ah, 02h
int 21h
JMP MIDDLE


MIDDLE:
add bx, 3
mov dl, [bx]
add dl, 30h
mov ah, 02h
int 21h

JMP END

END:


this is the code i wrote. it works for the matrix
1, 2, 3,
4, 5, 6,
7, 8, 9 and print 1, 4, 7, 8, 9, 6, 3, 2, 5



zemzi

Could someone help me, how to transform my code above, because it works only for 3x3 matrix, must work for matrix witn N dimensions example. 3x4 , 4x5 etc.

This is my task:

Matrix given in memory to print the spiral in opposite direction from clockwise (left column down the right lower range, right up column, a series of upper left, etc. until you get to the middle)Every suggestion is welcome.Thanks

I need algorithm for this task... in emu 8086

qWord

Quote from: zemzi on January 05, 2012, 09:00:51 PMI need algorithm for this task...
You need two interleaved loops: one for the rows and one for the columns. The count direction of this loops determine how you go through the matrix.
FPU in a trice: SmplMath
It's that simple!

zemzi

Could you give me some example of code, how to write that!!!!

zemzi

Here I have code in C, I need help to translate this in assembly emu 8086. Please help me if you know

#include <stdio.h>
#include <stdlib.h>

int main(void) {

int **mat; // Pointer to pointer
int rows, cols, i, j;
printf("How many rows you want ");
scanf("%d", &rows);
//rows = 10;
//cols = 10;
mat = malloc(rows*sizeof(int*)); // array of number of rows


printf("How many cols ");
scanf("%d", &cols);
for (i=0; i<rows; i++) { // for each row ...
mat[i] = malloc(cols * sizeof(int)); // add these many cols
}
for (i = 0; i<rows; i++) {
for (j = 0; j<cols; j++) {
mat[i][j] = (i+1) * (j+1);
printf("%4d ", mat[i][j]); //these two print lines
//printf("%4d ", *(*(mat+i)+j)); //do the same thing
}
putchar('\n');
}
for(i=0;i<rows;i++) //free malloc'd memory
free(mat[i]); //rows first
free(mat); //then the array pointer itself

printf("\n\n");
return 0;
}

dedndave

for 16-bit .COM programs, you already own the memory up to the 640 kb limit (or however much RAM they have)
for 16-bit .EXE programs, you have to "free" paragraphs in the heap

i will play with this later today, if i have time
the reason you aren't getting a lot of help, here, is because this is 16-bit code   :P
in the 32-bit world, it would be very easy - and a lot more members are willing to play with it

in the C code, i assume they are 16-bit int's, right ?

dedndave

ok - got some time to play
let me see if i can remember how to free and allocate memory under DOS   :P
once we get past that, the matrix part is easy

dedndave

welllll
i am trying to remember how i used to go about free'ing memory
the function is INT 21h, AH=4Ah
but, i forget how i arrived at the address of memory to free   :P

under DOS, the heap is a "chain" of memory allocation blocks
the block header is 16 bytes and chains to the next allocation header
the 16 byte area just below the PSP contains the block header for the current EXE
i may have used the information from that to calculate the address of the next block
another approach would be to calculate the highest used address by adding the stack segment and stack bottom

let me play some more   :P

qWord

he is using emu 8086 - a quick view to the documentation shows that allocations functions are not available (?).
The question is: does he really need dynamically allocation? He could simply use the stack, because only one allcation is needed.
FPU in a trice: SmplMath
It's that simple!

dedndave

thanks qWord   :U

yah - for that matter, he could just declare a 64 kb far data segment   :P
or - simply write the program as a .COM - then he owns the memory

now, it's gonna bug me until i remember, though - lol
i used to have a book by Ray Duncan that had the info

i think the .COM method is easiest   :8)

dedndave

ok - played with allocation a bit   :bg
by using ExeHdr.exe from the MASM ver 5.10 package, i managed to figure out how things work - sorta

in the MZ EXE header, there is a word that tells the OS what the maximum allocation size is
this value can be set during link by using the /CPARMAXALLOC switch or modified with ExeMod.exe
by default, the linker sets it to 0FFFFh, requesting all available memory

what that means is, the EXE owns all available memory in the heap
so, to calculate the end of the EXE in memory, you can use the stack segment and initial stack pointer
then, free all available memory above that address
after that, you can allocate memory, as needed   :U

you can eliminate some code by using ExeMod.exe and set the maximum allocation to the same size as the minimum
but, that seems like a little bit of a hassle   :P

for running under emu8086, we can assume that we own all memory
all we have to do is verify there is sufficient memory available and create a segment above SS:SP

FORTRANS

Hi Dave,

   By default *.EXE and *.COM programs own all of the
conventional memory.  You can free the memory with function
4AH or using the linker options, but just using the memory is
simpler.  Use assembler, linker, and CREF to generate a listing
and a MAP file to see where your segments are.  My usual
builds have the stack first in memory, followed by data, and code.

   The second word in the PSP shows how much memory is
owned by your program.  Using a program listing or map file
you just point a segment register past the end of your program
and below the the PSP value, and chunk away.  If you want
to automate some of that, create another  segment in your
program and use that for less than 64k of memory.  That has
the advantage of throwing a load error if the memory is not
available.

   The "free memory to then allocate it" seems to be a nasty
leftover from a C programmer's paradigm.

Cheers,

Steve N.

dedndave

yes Steve, i saw that function (4Ah), which is for resizing an existing allocation
in some cases, it may be the way to go, as you can save 16 bytes of RAM by eliminating an allocation header   :bg
i had forgotten about that word at PSP:0002, though   :U

QuoteThe "free memory to then allocate it" seems to be a nasty
leftover from a C programmer's paradigm.

not all that bad, actually
you are dealing with memory between the top of your program and the end of available memory
when you are done, it winds up being one big block because DOS "coallesces" it

dedndave

ok - i can fill the array
but, i am not sure i understand what you want for output
the first one seems simple enough
but - the second one ?

Farabi

I think My code on Lab subforum is working, you dont need to run it on DOS, but run it on 32-bit environtment since 16-bit mode is obsolete.
Those who had universe knowledges can control the world by a micro processor.
http://www.wix.com/farabio/firstpage

"Etos siperi elegi"