Reputation: 96
I'm already nervous about posting this question, but here it goes. Im attempting to design an Assembly Program to take in two integers, then take in an operand (*, +, or ^). Then, depending on the operand, the program will perform the arithmetic sequence based on the operand chosen. The output has to look exactly like this, lets say the user inputs 5, then the user inputs 6, and lastly the user inputs a *, the program must print out
OP 5 * 6 = 30
Now, I cannot grasp the concept of printf for some reason, so my printfunction at the bottom is my ridiculous way of attempting to print this out. If someone could explain to me how printf works, id love to hear it! I have very basic knowledge of the stack. Also, I do not have the exponential function in this, because I have no idea how to do it in assembly language. And lastly, I have a non program related question for the true computer gods out there...I absolutely hate assembly language, I have trouble writing basic operations in this language. I loved working in C, CPP, and Java...is this langauge absolutely necessary to survival in a programmers day to day, or is this a history lesson on how people made fire before they had lighters? Anyway, any answers to any questions are welcome, and thank you in advance.
;program to add, multiply, or give the power of a number
%include "asm_io.inc"
segment .data
prompt1 db "Enter a number: ", 0 ;prompts
prompt2 db "Enter another number: ", 0
prompt3 db "Enter an operand", 0
prompt4 db "OP ", 0 ;idiotic prompts for printing
prompt5 db " = ", 0 ;another printing prompt
segment .bss
num1 resd 1 ;variable for 1st number
num2 resd 1 ;variable for 2nd number
op resd 1 ;variable for operand
segment .text
global asm_main
asm_main:
enter 0,0 ; setup routine
pusha
restart:
mov eax, prompt1 ; print out prompt
call print_string
call print_nl
call read_int ; read integer
mov [num1], eax ; store into num1
call print_nl
mov eax, prompt2 ; print out prompt
call print_string
call print_nl
call read_int ; read integer
mov [num2], eax ; store into num2
call print_nl
mov eax, promtp3 ;print out prompt
call print_string
call print_nl
call read_char ;read operand and dispose of null
call read_char
mov [op], eax ;store operand in [op]
call print_nl
cmp [op], '*' ;operand comparison
jne jmp1
call mulFun
jmp restart
jmp1: cmp [op], '+' ;operand comparison
jne jmp2
call sumFun
jmp restart
jmp2: cmp [op], '^' ;operand comparison
jne jmp3
call expFun
jmp restart
jmp3: cmp [op], 'e' ;exit function
je end1
end1:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
call print_nl ; pr
popa
mov eax, 0 ; return back to C
leave
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mulfun: ;multiplication function
mov ebx, [num1]
mov ecx, [num2]
imul ebx, ecx
jmp printFun
sumFun: ;sum function
mov ebx, [num1]
mov ecx, [num2]
add ebx, ecx
call printFun
printFun: ;printing function
mov eax, [prompt4]
call print_string
mov eax, [num1]
call print_string
mov eax, [op]
call print_string
mov eax, [num2]
call print_string
mov eax, [prompt5]
call print_string
mov eax, ebx
call print_string
call print_nl
ret
Upvotes: 2
Views: 1370
Reputation: 47593
Everywhere I found an issue I have added *** in the comments. A few things to note:
cmp [op], '+'
the size of the data [op] refers to has to be specified so you prefix it with the size. Size can be byte, word, dword. You are comparing a single character so the size would be byte . The code should have looked like this cmp byte [op], '+'
mov eax, varname
this moves the address of varname to EAX. If you want to move the contents of varname you have to surround it with square brackets like mov eax, [varname]
. When dealing with string addresses and the print_string routine you need to pass the address of the string in EAX, not the contents. So leave out the brackets.call
to call a function, your function should end with a ret
.jmp
to a function, use call
The revised code is as follows:
;program to add, multiply, or give the power of a number
%include "asm_io.inc"
segment .data
prompt1 db "Enter a number: ", 0 ;prompts
prompt2 db "Enter another number: ", 0
prompt3 db "Enter an operand", 0
prompt4 db "OP ", 0 ;idiotic prompts for printing
prompt5 db " = ", 0 ;another printing prompt
segment .bss
num1 resd 1 ;variable for 1st number
num2 resd 1 ;variable for 2nd number
op resd 1 ;variable for operand
segment .text
global asm_main
asm_main:
enter 0,0 ; setup routine
pusha
restart:
mov eax, prompt1 ; print out prompt
call print_string
call print_nl
call read_int ; read integer
mov [num1], eax ; store into num1
call print_nl
mov eax, prompt2 ; print out prompt
call print_string
call print_nl
call read_int ; read integer
mov [num2], eax ; store into num2
call print_nl
mov eax, prompt3 ;print out prompt
;*** Typo - promtp3 changed to prompt3
call print_string
call print_nl
call read_char ;read operand and dispose of null
call read_char
mov [op], eax ;store operand in [op]
call print_nl
cmp byte [op], '*' ;operand comparison
;*** We must specify the size of data we are
;*** comparing, so we tell the assembler that
;*** with 'byte' in front of the variable
jne jmp1
call mulFun
jmp restart
jmp1: cmp byte [op], '+' ;operand comparison
;*** We must specify the size of data we are
;*** comparing, so we tell the assembler that
;*** with 'byte' in front of the variable
jne jmp2
call sumFun
jmp restart
jmp2: cmp byte [op], '^' ;operand comparison
;*** We must specify the size of data we are
;*** comparing, so we tell the assembler that
;*** with 'byte' in front of the variable
jne jmp3
; call expFun ;*** This expFun function doesn't exist so
;*** don't call it so we can compile and link
jmp restart
jmp3: cmp byte [op], 'e' ;exit function
;*** We must specify the size of data we are
;*** comparing, so we tell the assembler that
;*** with 'byte' in front of the variable
je end1
end1:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
call print_nl ; pr
popa
mov eax, 0 ; return back to C
leave
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mulFun: ;multiplication function
;*** NASM is case sensitive - changed mulfun to mulFun
mov ebx, [num1]
mov ecx, [num2]
imul ebx, ecx
call printFun ;*** Call printFun, don't 'jmp' to it
ret ;*** Since mulfun was called, we use 'ret' to return
sumFun: ;sum function
mov ebx, [num1]
mov ecx, [num2]
add ebx, ecx
call printFun
ret
printFun: ;printing function
mov eax, prompt4 ;*** We want the address of prompt4, not what is at prompt4
;*** Remove the brackets from [prompt4]
call print_string
mov eax, [num1]
call print_int ;*** Use print_int to print an integer, not print_string
mov eax, [op]
call print_char ;*** Use print_char to print a char, not print_string
mov eax, [num2]
call print_int ;*** Use print_int to print an integer, not print_string
mov eax, prompt5 ;*** We want the address of prompt5, not what is at prompt5
;*** Remove the brackets from [prompt5]
call print_string
mov eax, ebx
call print_int ;*** Use print_int to print an integer, not print_string;
call print_nl
ret
I will leave it up to the original poster to develop the expFun function. For the time being I have commented it out so the existing code can be assembled, linked, and run.
You can use printf but I think the long way can teach a few things too, and I have excluded a discussion of printf from my answer. Your instructor, course material, teacher assistant would be a good place to start with your other questions.
This answer is being provided to get your program into a usable state so that you can proceed with the assignment. In my opinion the original question is too broad. If further help is needed it is probably best to ask a new question with a specific issue.
Upvotes: 4