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?

New Topic/Question
Reply



MultiQuote






|