Hello. I urgently need a program in assembler, for a x86, in Linux.
The program has to do the following:
- Read from the keyboard a function of x. Example: "x+2-x^3*9"
*) The function has to be in the form of dododod (d=digit [0-9], 0=operator [+,-,*,/,^]),
*) Therefore, it does not admit 2 operators or 2 digits together (like "12^-x"),
*) No error handling needed, it is assumed that the entered values are correct
- Read from the keyboard the value of x. Example: "1"
- Show the result of the function with that value of x (in the example it would be "-6")
I'm really newby to assembler programming so I would really preciate if someone could give me a hand "for the love of the game".
Best regards!
The program has to do the following:
- Read from the keyboard a function of x. Example: "x+2-x^3*9"
*) The function has to be in the form of dododod (d=digit [0-9], 0=operator [+,-,*,/,^]),
*) Therefore, it does not admit 2 operators or 2 digits together (like "12^-x"),
*) No error handling needed, it is assumed that the entered values are correct
- Read from the keyboard the value of x. Example: "1"
- Show the result of the function with that value of x (in the example it would be "-6")
I'm really newby to assembler programming so I would really preciate if someone could give me a hand "for the love of the game".
Best regards!
Please read the community rules. This is not _we_do_your_homework_ forum.
I'm really newby to assembler programming so I would really preciate if someone could give me a hand "for the love of the game".
You have to ask a question before we can attempt to help you. Also, you have to be a little more specific than just laying out your requirements.
Now, I have a few questions for you.
1) How much of the source is "complete"???
2) Which part's' are you having trouble with???
3) Why the urgency if you are "new to assembly language"???
Sorry about that, I was not familiarized with the rules since I'm new to the forum.
Let me reformulate the question then:
Does anyone have an example or a piece of code that can help me or lead me to the solution?
Any help will be appreciated.
Let me reformulate the question then:
Does anyone have an example or a piece of code that can help me or lead me to the solution?
Any help will be appreciated.
1) How much of the source is "complete"???
What i have is what follows:
2) Which part's' are you having trouble with???
I'm having trouble parsing the string of the formula input. I can't find the way to read character by character the string, to put the operands and the operators in a stack for the calculations. As you can see, I'm using AT&T notation and what I'm doing to compile the code is the following, in Red Hat:
*) Open a terminal
*) Go to the folder which contains the code
*) Execute the next command "gcc -o "
3) Why the urgency if you are "new to assembly language"???
The urgency is that my teacher is kinda crazy. He believes in the investigative capabilities of his students to solve any problem he can think of, while he does not have a clue of the assembly language. I'm in summer so the period of classes is really short and he gave us a week to get the project done.
Thanks in advance.
What i have is what follows:
.data
function: .string " "
valx: .int 0
t_int: .string "%d"
t_str: .string "%s"
title1: .string "Enter the function: "
title2: .string "Enter the value of x: "
linefeed: .string "\n"
.text
.global main
main:
pushl $title1 #push in the stack the first title
pushl $t_str #push in the stack the type of value
call printf #print the output
addl $8,%esp #clear the stack
movl $3,%eax
int $0x80 #call the interupt for printing
pushl $function #push in the stack the function variable
pushl $t_str #push in the stack the type of value
call scanf #read the input
addl $8,%esp #clear the stack
pushl $title2 #push in the stack the second title
pushl $t_str #push in the stack the type of value
call printf #print the output
addl $8,%esp #clear the stack
movl $3,%eax
int $0x80 #call the interrupt for printing
pushl $valx #push in the stack the receiving variable
pushl $t_int #push in the stack the data type
call scanf #read the input
addl $8,%esp #clear the stack
pushl $linefeed #push in the stack the string of linefeed
pushl $t_str #push in the stack the data type
call printf #print the linefeed
addl $8,%esp #clear the stack
movl $3,%eax
int $0x80 #call the interruption for printing
ret
#this is the section where I want to parse char by char the input stored in the "function" variable, but I don't
#know how. Then I would have to calculate the result of the function and show the output.
2) Which part's' are you having trouble with???
I'm having trouble parsing the string of the formula input. I can't find the way to read character by character the string, to put the operands and the operators in a stack for the calculations. As you can see, I'm using AT&T notation and what I'm doing to compile the code is the following, in Red Hat:
*) Open a terminal
*) Go to the folder which contains the code
*) Execute the next command "gcc -o "
3) Why the urgency if you are "new to assembly language"???
The urgency is that my teacher is kinda crazy. He believes in the investigative capabilities of his students to solve any problem he can think of, while he does not have a clue of the assembly language. I'm in summer so the period of classes is really short and he gave us a week to get the project done.
Thanks in advance.
Well.., there are plenty of algorithms for making an expression evaluator. Here is one of the simplest approaches:
(assuming the conditions you have stated are preserved)
1) Get the expression (for example x+2-x^3*9).
2) Get the value of 'x'.
3) Construct new expression by converting any ASCII representation of a digit to it's binary form. Replace any occurrence of 'x' with appropriate value.
So from x+2-x^3*9 you will get something like this (hexadecimal representation):
00000001 + 00000002 - 00000001 ^ 00000003 * 00000009
4) Search for operator with a higher mathematical precedence.
5) Apply the operation on the nearby digits.
6) Reconstruct the expression.
7) Repeat last three steps
E.g.:
00000001 + 00000002 - 00000001 ^ 00000003 * 00000009
00000001 + 00000002 - 00000001 * 00000009
00000001 + 00000002 - 00000009
00000003 - 00000009
FFFFFFFA
The urgency is that my teacher is kinda crazy.Šnbsp;
He surely is. Teaching AT&T syntax.... eeeewww!
(assuming the conditions you have stated are preserved)
1) Get the expression (for example x+2-x^3*9).
2) Get the value of 'x'.
3) Construct new expression by converting any ASCII representation of a digit to it's binary form. Replace any occurrence of 'x' with appropriate value.
So from x+2-x^3*9 you will get something like this (hexadecimal representation):
00000001 + 00000002 - 00000001 ^ 00000003 * 00000009
4) Search for operator with a higher mathematical precedence.
5) Apply the operation on the nearby digits.
6) Reconstruct the expression.
7) Repeat last three steps
E.g.:
00000001 + 00000002 - 00000001 ^ 00000003 * 00000009
00000001 + 00000002 - 00000001 * 00000009
00000001 + 00000002 - 00000009
00000003 - 00000009
FFFFFFFA
The urgency is that my teacher is kinda crazy.Šnbsp;
He surely is. Teaching AT&T syntax.... eeeewww!
I do know the step by step algorithm, the codification is what I'm struglin with. Haven't advanced much... how do I get the first digit from the function?
By the way, Intel notation would be great too.
There is nothing really to "codify", as the resultant string returned from scanf should be in ASCII format.
arafel touched upon the fact that you have to convert "any ASCII representation of a digit to it's binary form", so this would be your next step.
Personally, for a simple project like this that requires no error-checking, I would go for a counter mechanism...
Note that EBX *should* be BYTE aligned and hence on an "even address". So each "Digit" should be on an even BYTE address (dododo)... and each "Operation" should be on an odd BYTE address (dododo).
Just fill in the blanks with your own ideas on how to process ASCII code and the "order of operations" list.
Another thing I noticed with your code, is the unnecessary use of "pushl $t_str" in your printf routines. The strings are already in "%s" format (ASCII text with a null-terminator), so there is no need to add this extra step. You *do* need it for scanf though, as that is how the function defines the input.
arafel touched upon the fact that you have to convert "any ASCII representation of a digit to it's binary form", so this would be your next step.
Personally, for a simple project like this that requires no error-checking, I would go for a counter mechanism...
;!!!!!NASM syntax!!!!!
;Parse the function input
mov ebx,DWORD function ;ASSUMED TO BE ALIGNED TO AN "EVEN" ADDRESS
mov al,BYTE
cmp al,0
jnz continue_parsing
ret ;reached the string "null terminator" (\0)... so return/exit
;Test if EBX is odd (operation) or even (digit)
continue_parsing:
test bl,1 ;Test if EBX is odd or even
jnz process_operation ;Even = Process a "Digit", Odd = process an "Operation"
process_digit:
;todo: check for ASCII byte value between 30h-39h
; Yes-> Subtract 30h from the byte value, and use for later
; No-> Fail/Exit (no error handling)
process_operation:
;todo: check for ASCII values of "+-*/^..." in order (like a switch statement)
; Found-> Process that operation into an "order of operation" list
; Not Found -> Fail/Exit (no error handling)
inc ebx
jmp parse
Note that EBX *should* be BYTE aligned and hence on an "even address". So each "Digit" should be on an even BYTE address (dododo)... and each "Operation" should be on an odd BYTE address (dododo).
Just fill in the blanks with your own ideas on how to process ASCII code and the "order of operations" list.
Another thing I noticed with your code, is the unnecessary use of "pushl $t_str" in your printf routines. The strings are already in "%s" format (ASCII text with a null-terminator), so there is no need to add this extra step. You *do* need it for scanf though, as that is how the function defines the input.
Hello, guess what? I decided to move to Intel syntaxis.
I have the following code:
As you can see, I want to display the result of adding the first two digits entered in the function (just for testing purposes, in the main problem you aren't supposed to enter a digit followed by another). The problem is that when I enter in the function "12", it is displaying a "c" as te result of the sum (1+2=third letter from the alphabet -> c); when I enter "23", it is displaying an "e" as the result of the sum; etc etc. What am I doing wrong? What do I have to change to display the correct value?
I have the following code:
title1: db 'Enter the function: ',10
title1Len equ $-title1
global main
main:
mov eax, 4 #system output
mov ebx, 1 #standard output
mov ecx, title1 #variable to print
mov edx, title1Len #length to print
int 80h #system interrupt
mov eax, 3 #system input
mov ebx, 0 #standard input
mov ecx, function #variable to receive the input
mov edx, 25 #max length to receive
int 80h #system interrupt
mov eax, #store in eax the first digit
mov ebx, #store in ebx the second digit
add eax, ebx #add the two digits
mov , eax #store the result in 'digit' variable
mov eax, 4 #system output
mov ebx, 1 #standard output
mov ecx, digit #variable to print
mov edx, 1 #length to print
int 80h #system interrupt
mov eax, 1 #finalitation of the program
mov ebx, 0 #finalitation of the program
int 80h #finalitation of the program
ret
function resb 25
function resb 1
As you can see, I want to display the result of adding the first two digits entered in the function (just for testing purposes, in the main problem you aren't supposed to enter a digit followed by another). The problem is that when I enter in the function "12", it is displaying a "c" as te result of the sum (1+2=third letter from the alphabet -> c); when I enter "23", it is displaying an "e" as the result of the sum; etc etc. What am I doing wrong? What do I have to change to display the correct value?
Please study an ASCII Chart to understand what you are working with. You are confusing a string representation of a digit (ASCII) with a binary representation that a computer uses for mathematical operations.
If you notice the chart from the link above, '1'(31h) + '2'(32h) = 'c'(63h). As well as '2'(32h) + '3'(33h) = 'e'(65h).
This means you are not converting the ASCII Characters to Binary before performing mathematical operations, which was mentioned multiple times.
If you checked for a value between 30h and 39h (valid ASCII representation of numbers 0 through 9), and then subtracted 30h from that value... it would give you the converted binary number you need (i.e. '1'(31h) - "ASCII Digit Base"(30h) = 1(01h) ). In order to printf that number, you would simply add %i to the string (and the accompanying variable), and printf will automatically convert that Binary Digit 3(03h)/5(05h) back to an ASCII representation '3'(33h)/'5'(35h).
In short, you *really* need to study the differences between ASCII and Binary... or you will not make your deadline.
In order to help you on your way, I will post a generic "quick fix" (no error checking or optimization) of your code, study it until it "clicks"...
If you notice the chart from the link above, '1'(31h) + '2'(32h) = 'c'(63h). As well as '2'(32h) + '3'(33h) = 'e'(65h).
This means you are not converting the ASCII Characters to Binary before performing mathematical operations, which was mentioned multiple times.
If you checked for a value between 30h and 39h (valid ASCII representation of numbers 0 through 9), and then subtracted 30h from that value... it would give you the converted binary number you need (i.e. '1'(31h) - "ASCII Digit Base"(30h) = 1(01h) ). In order to printf that number, you would simply add %i to the string (and the accompanying variable), and printf will automatically convert that Binary Digit 3(03h)/5(05h) back to an ASCII representation '3'(33h)/'5'(35h).
In short, you *really* need to study the differences between ASCII and Binary... or you will not make your deadline.
In order to help you on your way, I will post a generic "quick fix" (no error checking or optimization) of your code, study it until it "clicks"...
mov al, BYTE #store in al the first digit (ASCII = 1 Byte)
mov ah, BYTE #store in ah the second digit (ASCII = 1 Byte)
sub al, 30h #convert the first ASCII digit to Binary form
sub ah, 30h #convert the second ASCII digit to Binary form
add al,ah #add the two digits
mov BYTE,al #store the result in 'digit' variable