1 Replies - 1455 Views - Last Post: 15 March 2012 - 04:05 PM

#1 MrJabbaNoHere  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 29
  • Joined: 08-March 11

Infix to Postfix Conversion Assembly

Posted 14 March 2012 - 07:56 PM

Greetings,

For an assignment, I am required to write an assembly program that will convert an infix string that may consist of +,-,*,/,(,) and their operands. I also the C code from which I have based my assembly code off of. I am working on x86 intel architecture (that is what we are learning in class). The C code works in any case, my assembly code compiles but does not convert the string (for example, I enter 5+5, and 5+5 is returned when it should be 55+). My best guess is that I am not using the stack properly. I will include my main program, my C function, and my assembly code. My question is, obviously, where I am going wrong? Thank you for your time and help


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

extern void toPostfix(char* , char* );


int main(void) {
	
	char  infixstream[100]={0};
	char  postfixstream[100]={0};
	int i;
	printf("\n Enter a mathematical expression: ");
	scanf("%s",infixstream);
	printf("\n");
	toPostfix(infixstream,postfixstream);
	printf("\n The postfix equivalent of the input  expression: ");
	printf("%s",postfixstream);
	printf("\n");
	return EXIT_SUCCESS;
}


C Code:
void toPostfix(char* infixstream, char* postfixstream)
{
	int i=0, p=0, s=0; // counters for infix, postfix, stack respectively
	char stack[100];
loop:
	if(infixstream[i] == '\0')
		goto miniloop2;
	if(infixstream[i] == '*')
		goto checkmultdiv;
	if(infixstream[i] != '/')
		goto addsubcheck;
checkmultdiv:

	if(stack[s-1] =='*')
		goto removeone;
	if(stack[s-1] !='/')
		goto pushtostack;
removeone:
	postfixstream[p]=stack[s-1];
	s--;
	p++;
pushtostack:
	stack[s]=infixstream[i];
	s++;
	goto incrementi;
addsubcheck:
	if(infixstream[i] == '+')
		goto removesome;
	if(infixstream[i] != '-')
		goto openparencheck;
removesome:
	if(s==0)
		goto pushtostack;
	if(stack[s-1]=='(')
		goto pushtostack;
	postfixstream[p]=stack[s-1];
	s--;
	p++;
	goto removesome;
openparencheck:
	if(infixstream[i]!='(')
		goto closeparencheck;
	goto pushtostack;
closeparencheck:
	if(infixstream[i]!=')')
		goto pushtopost;
miniloop:
	if(stack[s-1]=='(')
		goto decerements;
	postfixstream[p]=stack[s-1];
	s--;
	p++;
	goto miniloop;
decerements:
	s--;
	goto incrementi;
pushtopost:
	postfixstream[p]=infixstream[i];
	p++;
incrementi:
	i++;
	goto loop;
miniloop2:
	if(s==0)
		goto out;
	postfixstream[p]=stack[s-1];
	s--;
	p++;
out:
	s=0;
}]


Assembly Code:
.globl _toPostfix
_toPostfix:

pushl %ebp
movl %esp,%ebp
movl 8(%ebp),%ebx /*move base address of infix stream into ebx*/
movl 12(%ebp),%eax /*move base address of postfix stream into eax*/
xorl %esi,%esi /* counter for infix stream */
xorl %edi,%edi /* counter for postfix stream */
xorl %ecx,%ecx /* counter for stack */

loop:
cmpl $0x0,(%ebx,%esi,1)/* If infix index equal to NULL */
je miniloop2
cmpl $0x2A, (%ebx,%esi,1)/* If infix index equal to '*' */
je checkmultdiv
cmpl $0x2F, (%ebx,%esi,1) /* If infix index not equal to '/'*/
jne addsubcheck

checkmultdiv:
cmpl $0x2A,4(%esp) /* If esp+4 (second-to-top stack value) equal to '*' */
je removeone
cmpl $0x2F,4(%esp) /* If not equal to '/'*/
jne pushtostack

removeone:
movl 4(%esp),%edx /* edx is temporary storage because we cannot copy from one memory address to another */
movl %edx,(%eax,%edi,1) /* effectively copy esp+4 into postfix stream index */
xorl %edx,%edx /*clears temporary storage edx*/
popl %esp /* esp = esp+4 */
decl %ecx /* decrement stack counter */
incl %edi /*increment postfix counter */

pushtostack:
pushl (%ebx,%esi,1)
incl %ecx
jmp incrementi

addsubcheck:
cmpl $0x2B,(%ebx,%esi,1) /* If equal to '+' */
je removesome
cmpl $0x2D,(%ebx,%esi,1) /* If not equal to '-'*/
jne openparencheck

removesome:
cmpl $0,%ecx /* If stack counter equal to 0 */
je pushtostack
cmpl $0x28, 4(%esp)/* If equal to '(' */
je pushtostack
movl 4(%esp),%edx
movl %edx,(%eax,%edi,1)
xor %edx,%edx
decl %ecx
incl %edi
jmp removesome

openparencheck:
cmpl $0x28,(%ebx,%esi,1) /* If not equal to '('*/
jne closeparencheck
jmp pushtostack

closeparencheck:
cmpl $0x29, (%ebx,%esi,1) /* If not equal to ')'*/
jne pushtopost

miniloop:
cmpl $0x28,4(%esp) /* If second highest value on stack equal to '(' */
je decrements
movl 4(%esp),%edx
movl %edx,(%eax,%edi,1)
xor %edx,%edx
decl %ecx
incl %edi
jmp miniloop

decrements:
decl %ecx
jmp incrementi

pushtopost:
movl (%ebx,%esi,1),%edx
movl %edx,(%eax,%edi,1)
incl %edi

incrementi:
incl %esi
jmp loop

miniloop2:
cmp $0,%ecx /* If equal to 0 */
je out
movl 4(%esp),%edx
movl %edx,(%eax,%edi,1)
xorl %edx,%edx
decl %ecx
incl %edi

out:
popl %ebp
ret



Also, I previously had written all of my compare statements like so:

cmpl '*',(%ebx,%esi,1)

But was receiving memory referencing errors. I don't know why, but I switched to using the ASCII equivalents for these characters. Are these correct? Perhaps that is why my code is not working?

Is This A Good Question/Topic? 0
  • +

Replies To: Infix to Postfix Conversion Assembly

#2 GunnerInc  Icon User is offline

  • "Hurry up and wait"
  • member icon




Reputation: 719
  • View blog
  • Posts: 1,978
  • Joined: 28-March 11

Re: Infix to Postfix Conversion Assembly

Posted 15 March 2012 - 04:05 PM

There should be a switch in your C compiler to output an asm listing. That would be the easiest way to learn from since the c code is working.

You set up a stack frame so the value you are expecting at esp + 4 is wrong, it should be esp + 8 since you are pushing ebp onto the stack.

Since you are setting up a stack frame you should be using ebp and not esp. ebp + 8, ebp + 12 etc..

If you don't need a stack frame, then don't push ebp and set ebp to esp then you can use esp + 4, esp + 8 etc, but then if/when you push something you will have to keep track of the stack pointers.

Also, since you are pushing 2 items on to the stack for your proc, you should not use just ret, but ret 4 * NumOfParams. In your case it should be ret 8, unless you are adding 8 to esp after the call to your proc.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1