Jump to content


Check out our Community Blogs

Register and join over 40,000 other developers!


Recent Status Updates

View All Updates

Photo
- - - - -

matrix task in assembly 8086

matrix assembly

  • Please log in to reply
9 replies to this topic

#1 juce

juce

    CC Lurker

  • Just Joined
  • Pip
  • 5 posts

Posted 13 December 2011 - 09:44 AM

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)

I'm new here, I have to write code for the task above in assembly,could someone help me and explain me how to solve this task? Please
  • 0

#2 RhetoricalRuvim

RhetoricalRuvim

    JavaScript Programmer

  • Expert Member
  • PipPipPipPipPipPipPip
  • 1310 posts
  • Location:C:\Countries\US
  • Programming Language:C, Java, C++, PHP, Python, JavaScript

Posted 13 December 2011 - 11:33 AM

So the assignment would be if you have a matrix,
[ 
a b c d e 
f g h i j 
k l m n o 
p q r s t 
u v w x y 
]
, you have to print this?:
a b c d e j o t y x w v u p k f g h i n s r q l m


Do you have ideas for the algorithm you would use?



P.S. We wouldn't do your homework for you, just letting you know right away. But we'll try helping with what we can.
  • 0

#3 juce

juce

    CC Lurker

  • Just Joined
  • Pip
  • 5 posts

Posted 13 December 2011 - 01:41 PM

Ok thanks, for the example, it is really that will work on that way. I will try to do something, but I haven't experience with assembly. I hope you will help me when something go wrong with my code.
Thanks in advance
  • 0

#4 juce

juce

    CC Lurker

  • Just Joined
  • Pip
  • 5 posts

Posted 13 December 2011 - 04:28 PM

include <stdio.h>
#define R 3
#define C 6
void spiralPrint(int m, int n, int a[R][C])
{
int i, k = 0, l = 0;
/* k - starting row index
m - ending row index
l - starting column index
n - ending column index
i - iterator
*/
while (k < m && l < n)
{
/* Print the first row from the remaining rows */
for (i = l; i < n; ++i)
{
printf("%d ", a[k][i]);
}
k++;
/* Print the last column from the remaining columns */
for (i = k; i < m; ++i)
{
printf("%d ", a[i][n-1]);
}
n--;
/* Print the last row from the remaining rows */
if ( k < m)
{
for (i = n-1; i >= l; --i)
{
printf("%d ", a[m-1][i]);
}
m--;
}
/* Print the first column from the remaining columns */
if (l < n)
{
for (i = m-1; i >= k; --i)
{
printf("%d ", a[i][l]);
}
l++;
}
}
}
/* Driver program to test above functions */
int main()
{
int a[R][C] = { {1, 2, 3, 4, 5, 6},
{7, 8, 9, 10, 11, 12},
{13, 14, 15, 16, 17, 18}
};
spiralPrint(R, C, a);
return 0;
}

If somebody know how can I convert into assembly ?
  • 0

#5 RhetoricalRuvim

RhetoricalRuvim

    JavaScript Programmer

  • Expert Member
  • PipPipPipPipPipPipPip
  • 1310 posts
  • Location:C:\Countries\US
  • Programming Language:C, Java, C++, PHP, Python, JavaScript

Posted 13 December 2011 - 04:34 PM

Have you tested the code you wrote? It didn't even compile on my computer.

I mean, you wouldn't want to spend all that time converting the code into assembly language just to find out that the result does not work, if you know what I mean.
  • 0

#6 zemzela

zemzela

    CC Regular

  • Member
  • PipPipPip
  • 30 posts

Posted 13 December 2011 - 04:46 PM

#include<iostream>
using namespace std;

int a[4][4]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};

void spiral(int min_row,int max_col,int max_row,int min_col)
{
for(int i=min_col;i<=max_col;i++)
{
cout<<a[min_row][i]<<" ";
}
for(int i=min_row+1;i<=max_row;i++)
{
cout<<a[i][max_col]<<" ";
}
for(int i=max_col-1;i>=min_col;i--)
{
cout<<a[max_row][i]<<" ";
}
for(int i=max_row-1;i>min_row;i--)
{
cout<<a[i][min_col]<<" ";
}
if(min_row<max_row && min_col<max_col)
spiral(min_row+1,max_col-1,max_row-1,min_col+1);
}

int main()
{

spiral(0,3,3,0);
return 0;
}

This code works, but I don't use assembly, ask someone else....
  • 0

#7 RhetoricalRuvim

RhetoricalRuvim

    JavaScript Programmer

  • Expert Member
  • PipPipPipPipPipPipPip
  • 1310 posts
  • Location:C:\Countries\US
  • Programming Language:C, Java, C++, PHP, Python, JavaScript

Posted 13 December 2011 - 06:28 PM

You guys, please use CODE tags next time; instead of typing this:
#include "something"

rather type this:
[noparse]
#include "something"
[/noparse]

, and CodeCall would convert that to this:
#include "something"


* * *


I don't know about the functions, but how about some JavaScript code? The language doesn't matter, for now, because we first need to think of an algorithm.


The idea is, we need to try and see what we would need to do to do the task by hand, if we were asked to, but we also need to keep in mind some of the things the computer would need to have, in order to do what we're doing.

We would start at the top-left corner, and continue scanning to the right, at first; we'll need an X variable and a Y variable to keep track of our current position within the matrix array. When we "hit" the wall on the right, we'll need to start going down, rather than going to the right.

When we "hit" the bottom wall, we'll have to start going left, instead of down. Then, when we "hit" the wall on the left, we'll start going up, instead of going left. Finally, when we "hit" the top wall again, we'll start going to the right, and the whole process starts over, as we keep "hitting" walls.


The problem is, we'll end up in an endless loop if we don't do anything to the walls; therefore, we have to move walls as we hit walls. When we hit the wall on the right, and start going down, we'll have to move the wall behind us (the top wall; since we're going down, behind us would then be up). When we hit the next wall, we move the wall that's behind us at that point, and so on.

Moving the walls closer in prevents us from going past those walls, and re-doing numbers that we already passed. That way, we know that we passed every number in the matrix when the walls are so close together - or when the walls turn inside out (for example, the left wall is to the right of the right wall) - that we no longer have space to work with.


Putting all that into numbers - which is what we'll have to use in our program - , we'll need four "walls" : xmin, xmax, ymin, and ymax .
  • xmin is the left "wall" ; it's the minimum index that x can be.
  • xmax is the right "wall" ; it's the maximum index value that x can be.
  • ymin is the top "wall" ; the minimum value y can be.
  • ymax is the bottom "wall" ; the maximum value y can be.
To move a wall, we'll just have to increment or decrement the appropriate minimum or maximum variable value.

We'll, of course, have our navigation location coordinate variables, x and y ; y is the row index, and x is the column index.

And we'll also have a variable to tell us whether we're going right (1), down (2), left (3), or up (4): state .

Finally, we'll have a variable where to store the whole string, which we can output to the screen after we're done processing the numbers.



Here's the function in JavaScript that does the above:
// Copyright (C) 2011 By RhetoricalRuvim 
function spiral (arr){ 
	var x; 
	var y; 
	var xmin= 0; 
	var xmax= arr[0].length - 1; 
	var ymin= 0; 
	var ymax= arr.length - 1; 
	var state= 1; 
	var b= ""; 
	x= xmin; 
	y= ymin; 
	while (true){ 
		while (x > xmax){ 
			x--; 
			y++; 
			ymin++; 
			state= 2; 
		} 
		while (y > ymax){ 
			y--; 
			x--; 
			xmax--; 
			state= 3; 
		} 
		while (x < xmin){ 
			x++; 
			y--; 
			ymax--; 
			state= 4; 
		} 
		while (y < ymin){ 
			y++; 
			x++; 
			xmin++; 
			state= 1; 
		} 
		if (xmax < xmin) break; 
		if (ymax < ymin) break; 
		b += arr[y][x]; 
		b += " "; 
		if (state == 1) x++; 
		if (state == 2) y++; 
		if (state == 3) x--; 
		if (state == 4) y--; 
	} 
	return b; 
}




Also, to show an example of how to use the function, here's an HTML page using that code:
<!-- 
	Copyright (C) 2011 By RhetoricalRuvim 
--> 
<html> 
	<head> 
		<title> Spiral 1 </title> 
		<script type="text/javascript" src="spiral1.js"></script> 
	</head> 
	<body> 
		<h1> Spiral 1 </h1> 
		Please enter the matrix values: <BR> 
		<textarea id="mat1" cols="40" rows="10"></textarea> <BR> 
		<button onClick="work ();"> 
			Go 
		</button> 
		<BR> <BR> <BR> <BR> 
		<div id="ans"> 
			  
		</div> 
		<script type="text/javascript"> 
			var src= document.getElementById ("mat1"); 
			var txt= document.getElementById ("ans"); 
			function work (){ 
				var text= src.value; 
				var array1= text.split ("\r\n"); 
					// Some browsers like to treat new-line character sequences as "\n" , and not 
					// the DOS-style "\r\n" , so we have to be prepared for that. 
					if (! (array1.length - 1) ) array1= text.split ("\n"); 
				var array2; 
				var i; 
				var j; 
				for (i in array1){ 
					if (isNaN (parseInt (i))) continue; 
					array1[i]= array1[i].split (" "); 
					for (j= 0; j < array1[i].length; j++) if (array1[i][j]) array1[i][j]= parseFloat (array1[i][j]); 
				} 
				txt.innerHTML= spiral (array1); 
			} 
		</script> 
	</body> 
</html>




Typically, you just need to try doing the task yourself, or at least imagine how the task will be done, and then think of how all that stuff can be represented in numbers and variables, so that you can more easily code it.

As for the next step - converting higher-level code into assembly language - I would say learn assembly language, if you haven't yet, and/or look at the 8086/8088 instruction set, and think of what instructions, and how, you can use to accomplish the things that the higher-level code does. You don't have to learn every single instruction there is, but it would be a good idea to at least become familiar with that stuff.

It would also help you gain experience if you practice reading assembly language (or other) code; that way you can debug things better, and catch mistakes more easily.
  • -1

#8 juce

juce

    CC Lurker

  • Just Joined
  • Pip
  • 5 posts

Posted 14 December 2011 - 12:17 PM

I just read your explanation. Thanks for your advice, those were very useful for me. I look through instruction set of assembly, and I think it isn't so complicated. I will try to translate this code in assembly step by step. I hope that it will works this time:)
  • 0

#9 juce

juce

    CC Lurker

  • Just Joined
  • Pip
  • 5 posts

Posted 15 December 2011 - 07:57 AM

I try to solve this task in assembler 8086, there is my code. But it has some errors, could you please help me how to solve?

mov ecx,0
mov cl,[QDM]
mov ebx,ecx
mov edi,Matrix
mSpiral:
push edi

mov al,[edi];Output [edi]
push ecx

mov edx,ecx
mov ecx,edx
dec ecx
cmp ecx,0
jle mSkD1
mD1:
add edi,ebx
mov al,[edi];Output [edi]
loop mD1
mSkD1:

mov ecx,edx
dec ecx
cmp ecx,0
jle mSkD2
mD2:
inc edi
mov al,[edi];Output [edi]
loop mD2
mSkD2:

mov ecx,edx
dec ecx
cmp ecx,0
jle mSkD3
mD3:
sub edi,ebx
mov al,[edi];Output [edi]
loop mD3
mSkD3:

mov ecx,edx
sub ecx,2
cmp ecx,0
jle mSkD4
mD4:
dec edi
mov al,[edi];Output [edi]
loop mD4
mSkD4:

pop ecx

pop edi
add edi,ecx
inc edi

sub ecx,2
cmp ecx,0
jle mEx
jmp mSpiral
mEx:

Matrix db 0,1,2,3,4,5,6,7,8,9,0Ah,0Bh,0Ch,0Dh,0Eh,0Fh
QDM db 4;Matrix dimension
  • 0

#10 RhetoricalRuvim

RhetoricalRuvim

    JavaScript Programmer

  • Expert Member
  • PipPipPipPipPipPipPip
  • 1310 posts
  • Location:C:\Countries\US
  • Programming Language:C, Java, C++, PHP, Python, JavaScript

Posted 15 December 2011 - 04:57 PM

Again, please use CODE tags when posting code.

You just need to type this:
[noparse]
mov eax, [ebx]
[/noparse]

CodeCall's bbcode-parsing engine would convert that to this for you:
mov eax, [ebx]

* * *

Aside from the CODE tags, I thought you meant the code to be for Intel 8086 processors. Those don't have 32-bit registers, so you would probably at least not be able to store anything in the high-order words of the registers.

The other thing, what did you mean by this code?:
mov edx,ecx
mov ecx,edx

Because you don't need the second instruction in that code; since ECX and EDX are the same, after you set EDX equal to ECX in the first instruction, it wouldn't matter if you set ECX equal to EDX or not, in the second instruction.

For example, if ECX is A and EDX is B, then 'mov edx, ecx' would make both A, and since 'mov ecx, edx' would set ECX to A when it already is A, you don't need the 'mov ecx, edx' .

Also, what did you mean by this code?:
mov al,[edi];Output [edi]
push ecx

Here's what I got for outputting the byte integer at [noparse][EDI]:[/noparse]
;; Output what's at [EDI]. 
;; It's an integer, so we'll have to do some processing to output it. 
;; However, it's only an 8-bit value, so it shouldn't be too hard, really, 
;; so we can hard-code it. 
;; We'll need ECX and EDX for this, so we'll back them up. 
push ecx 
push edx 
	mov al,[edi];Output [edi] 
	and ah, 0                   ;; Another way of clearing (setting to 0) a register. 
	;; When we divide by a 16-bit value, we need to set the high-order word appropriately. 
	xor dx, dx 
	;; We'll divide by 100. 
	mov cx, 100 
	;; The actual dividing. 
	div cx 
	;; Output the value (digit). 
		;; The DX register contains the modulus, which we'll need, so 
		;; we need to back DX up before we can use it. 
		push dx 
			;; Add 48, to make it a character. 
			add al, 48 
			;; The output value is AL. 
			mov dl, al 
			;; The MS-DOS function code is 0x02 (output character). 
			mov ah, 0x02 
			;; Perform function. 
			int 0x21 
		;; Restore DX. 
		pop dx 
	;; Divide the modulus by 10. 
	mov ax, dx 
	xor dx, dx 
	mov cx, 10 
	div cx 
	;; Output the value (the next digit). 
		push dx 
			add al, 48 
			mov dl, al 
			mov ah, 0x02 
			int 0x21 
		pop dx 
	;; No need to divide the modulus, since dividing by 1 doesn't make sense. 
	add dl, 48 
	mov ah, 0x02 
	int 0x21 
	;; Output a new line. 
	mov dl, 13 
	int 0x21 
	mov dl, 10 
	int 0x21 
;; Let's restore ECX and EDX . 
pop edx 
pop ecx

  • 0





Also tagged with one or more of these keywords: matrix, assembly

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download