# Assembly Language

Page 1 of 1

## 8 Replies - 6969 Views - Last Post: 15 October 2008 - 02:35 PM

### #1 Wilbur

Reputation: 0
• Posts: 17
• Joined: 26-September 08

# Assembly Language

Posted 08 October 2008 - 10:07 AM

Ok. So I am trying to write an assembly program that will ask the user to input a number of pennies, nickels, dimes, and quarters. Then, it will calculate the total number of coins, dollars it adds up to, and cents left over. Here is what i have so far...

.586
.MODEL FLAT

INCLUDE io.h		; header file for input/output

.STACK 4096

.DATA
pennies DWORD   ?
nickels DWORD   ?
dimes DWORD   ?
quarters DWORD   ?
numberOfCoins DWORD ?
total DWORD ?
prompt1 BYTE	"How many pennies do you have?", 0
prompt2 BYTE	"How many nickels do you have?", 0
prompt3 BYTE	"How many dimes do you have?", 0
prompt4 BYTE	"How many quarters do you have?", 0
string  BYTE	   40 DUP (?)
resultLbl BYTE	"Coin Information", 0
sum	 BYTE	  11 DUP (?), 0

.CODE
_MainProc PROC
input	 prompt1, string, 40; read ASCII characters
atod	  string	; convert to integer
mov	  pennies, eax; store in memory

input	 prompt2, string, 40; repeat for second number
atod	  string
mov	  nickels, ebx

input	 prompt3, string, 40; read ASCII characters
atod	  string	; convert to integer
mov	  dimes, ecx; store in memory

input	 prompt4, string, 40; repeat for second number
atod	  string
mov	  quarters, edx

mov	 eax, pennies; pennies to EAX
mov	numberOfCoins, eax; numberOfCoins = number of pennies
mov	total, eax; total = pennies

mov	 ebx, nickels; nickels to EBX
mul	  numberOfNickels, 5; multiply numberOfNickels by 5
add	  total, ebx; total = total + 5*numberOfNickels

mov	ecx, dimes; dimes to ECX
mul	 numberOfDimes, 10; total = total + 10*numberOfDimes

mov	  edx, quarters; quarters to EDX
mul	   numberOfQuarters, 25; total = total + 25*numberofQuarters

dtoa	sum, eax; convert to ASCII characters
output  resultLbl, sum; output label and sum

mov	 eax, 0	; exit with return code 0
ret
_MainProc ENDP
END						; end of source code

I know the mul command doesn't have the right syntax, but I have no idea how to write that command. Also, I am currently using 4 different registers. Is there a way to use just the EAX register?

This post has been edited by Wilbur: 08 October 2008 - 10:10 AM

Is This A Good Question/Topic? 0

## Replies To: Assembly Language

### #2 TheFlipside

Reputation: 0
• Posts: 9
• Joined: 09-August 07

## Re: Assembly Language

Posted 09 October 2008 - 05:27 AM

Ok, first let me check if I understand it well...
You want to know if you can just use the EAX for the MUL opcode to multiply things?

Well to answer this question: Yes and there is no other way then using EAX.
MUL will put the final result of the operation in EAX, that is how the opcode is defined.

But I must confess that I don't understand your code...
First you declare the variables which is ok, but then you use in the main code several times the next command:
input	 prompt1, string, 40; read ASCII characters

And then you use different registers which suddenly appear to have the address (i suppose) as their value...
(first EAX, then EBX etc.)

A function always returns its result in the same register (probably EAX) or on the stack. To read from stack use:

POP EAX

this loads the first value from the stack into register EAX.

If this sounds all unfamiliar please read some tuts on the basics of assembler. When this is your first assembler project, then you are on the good way!

(I don't think it is usefull that I give you the correct code already, I assuming that you are trying to understand and learn, which means:
Usus Magister Est Optimus - Experience is the best teacher)

### #3 David W

• DIC supporter

Reputation: 298
• Posts: 1,839
• Joined: 20-September 08

## Re: Assembly Language

Posted 09 October 2008 - 07:37 AM

Quote

If this sounds all unfamiliar please read some tuts on the basics of assembler. When this is your first assembler project, then you are on the good way!

(I don't think it is usefull that I give you the correct code already, I assuming that you are trying to understand and learn, which means:
Usus Magister Est Optimus - Experience is the best teacher)

Try HLA ... a much more user friendly assember ... and here is an 'intro' course for it: ( at these links )

http://developers-he...index.php/topic,46.0.html

Here is a little demo HLA program ...

#include( "stdlib.hhf" )

// declare three integer variables in the static memory space

static
num1:   int32:=	23;   	// initialize num1 to 23
num2:   int32:=	77;   	// initialize num2 to 77
sum:	int32;				// sum is not initialized here

stdout.put( "The sum of ", num1, " and ", num2, " is " );

// eax is a 32 bit register in the microprocessor
mov( num1, eax );	// move the (value of the) integer num1 into eax
add( num2, eax );	// add the (value of the) integer num2 to (what's in) eax

mov( eax, sum );	// move the 32 bit value now in the eax register into the
// 32 bit static memory that we reserved as 'sum'

stdout.put( sum )

//  output a newline character(s)
stdout.newln();

// Also ... nl will output a newline character(s)
stdout.put( nl "Enter an integer " );
stdin.get( num1 );

stdout.put( nl "Enter a second integer " );
stdin.get( num2 );

stdout.put( nl "The sum of ", num1, " and ", num2, " is " );

mov( num1, eax );
mov( eax, sum );

stdout.put( sum, nl nl "The end." nl nl );

### #4 Wilbur

Reputation: 0
• Posts: 17
• Joined: 26-September 08

## Re: Assembly Language

Posted 09 October 2008 - 09:17 AM

TheFlipside, on 9 Oct, 2008 - 05:27 AM, said:

(I don't think it is usefull that I give you the correct code already, I assuming that you are trying to understand and learn, which means:
Usus Magister Est Optimus - Experience is the best teacher)

Thanks Flip. I definitely agree with you. As frustrating as writing good code can be, it is just something you have to mostly figure out on your own. Unless you struggle enough with it first, you will never learn anything. I will work on it some more this afternoon and repost tonight. I really appreciate your help!
~ Wilbur

This post has been edited by Wilbur: 09 October 2008 - 09:18 AM

### #5 David W

• DIC supporter

Reputation: 298
• Posts: 1,839
• Joined: 20-September 08

## Re: Assembly Language

Posted 10 October 2008 - 04:30 AM

Writing good code should be fun ... not frustrating.

Hey try HLA ... eh ?

See this HLA code I just put together to show you how HLA can make your work ... fun

program ChangeReturned;

#include( "stdlib.hhf" )

[email protected] := true;

procedure getCents; @returns( "eax" );
begin getCents;
try
stdout.puts( nl "Enter the number of cents to convert: " );
stdin.flushInput();
stdin.getu32(); // returns uns32 value input in eax
anyexception
mov( 0, eax ); // return ZERO if 'bad data' entered for 'cents' ...
stdout.puts( "Must enter a number in the range 0...(2^32 -1)." nl );
endtry;

end getCents;

procedure computeCoins( denomination: uns32; var amountLeft: uns32 ); @returns( "eax" );
begin computeCoins;
push( ebx );
push( edx );

mov( amountLeft, ebx ); // ebx holds the address of the value
mov( (type uns32 [ebx]), eax ); // eax now holds the VALUE of amountLeft //*1*//

// 'DIV' divides the 64 bit value in EDX:EAX by the operand
// leaving the quotient in EAX and the remainder in EDX.
// 'div' is used below ...

// Firstly, finish initializing the  'edx:eax' 64 bit 'register' ...
mov( 0, edx );

// int number = amountLeft / denomination;
div( denomination, edx:eax ); // Note that eax was set at //*1*// above
// mov( eax, number ); //Note: eax now holds the quotient i.e. the 'return value'

// and 'update' ... amountLeft = amountLeft % denomination;
mov( edx, (type uns32 [ebx]) ); // amountLeft value returned by ref

pop( edx );
pop( ebx );
// return number
// mov( number, eax ); // eax already holds the 'number'
end computeCoins;

procedure again; @returns( "al" );
begin again;
stdout.puts( nl nl "More (y/n) ? " );
stdin.flushInput();
stdin.getc();
if( !( al == 'n' || al =='N') ) then
mov( true, al );
else
mov( false, al );
endif;
end again;

procedure computeAndDisplay( cents: uns32 );
begin computeAndDisplay;

stdout.puts( nl stdio.tab "loonies	  : " );
stdout.putu32( computeCoins(100, cents) );

stdout.puts( nl stdio.tab "half-dollars : " );
stdout.putu32(  computeCoins(50, cents) );

stdout.puts( nl stdio.tab "quarters	 : " );
stdout.putu32(  computeCoins(25, cents) );

stdout.puts( nl stdio.tab "dimes		: " );
stdout.putu32(  computeCoins(10, cents) );

stdout.puts( nl stdio.tab "nickles	  : " );
stdout.putu32(  computeCoins( 5, cents) );

stdout.puts( nl stdio.tab "pennies	  : " );
stdout.putu32(  cents );

end computeAndDisplay;

begin ChangeReturned;

stdout.puts
(
"This program is intended to take 1-99 or more cents "
"and tell you how many" nl nl
stdio.tab "loonies	  :" nl
stdio.tab "half-dollars :" nl
stdio.tab "quarters	 :" nl
stdio.tab "dimes		:" nl
stdio.tab "nickles	  :" nl
stdio.tab "pennies	  :" nl
);
repeat
computeAndDisplay( getCents() );
until( !again() );

end ChangeReturned;

This post has been edited by David W: 10 October 2008 - 02:52 PM

### #6 Wilbur

Reputation: 0
• Posts: 17
• Joined: 26-September 08

## Re: Assembly Language

Posted 14 October 2008 - 11:13 AM

That does make a lot more sense. However, I need it written in 80x86 assembly language and I really don't understand how the mul operator is supposed to be used. I have worked with this program over the weekend and just have no idea where to go next. Any ideas/help would be greatly appreciated! This is my new code, although not much as changed other than changing all the registers to EAX.

; Purpose: Counting coins problem

.586
.MODEL FLAT

INCLUDE io.h		  ; header file for input/output

.STACK 4096

.DATA
pennies DWORD   ?
nickels DWORD   ?
dimes DWORD   ?
quarters DWORD   ?
numberOfCoins DWORD ?
total DWORD ?
prompt1 BYTE	"How many pennies do you have?", 0
prompt2 BYTE	"How many nickels do you have?", 0
prompt3 BYTE	"How many dimes do you have?", 0
prompt4 BYTE	"How many quarters do you have?", 0
string  BYTE	40 DUP (?)
resultLbl BYTE  "Coin Information", 0
sum	 BYTE	11 DUP (?), 0

.CODE
_MainProc PROC
input   prompt1, string, 40; read ASCII characters
atod	string			; convert to integer
mov	 pennies, eax	; store in memory

input   prompt2, string, 40; repeat for second number
atod	string
mov	 nickels, eax

input   prompt3, string, 40; read ASCII characters
atod	string			; convert to integer
mov	 dimes, eax		; store in memory

input   prompt4, string, 40; repeat for second number
atod	string
mov	 quarters, eax

mov		 eax, pennies	; pennies to EAX
mov		numberOfCoins, eax; numberOfCoins = number of pennies
mov		total, eax		; total = pennies

mov		eax, nickels	; nickels to EAX
mul		5			; multiply numberOfNickels by 5
add		total, eax		; total = total + 5*numberOfNickels

mov		eax, dimes		; dimes to EAX
mul		10			; total = total + 10*numberOfDimes

mov		eax, quarters			  ; quarters to EAX
mul		25					  ; total = total + 25*numberofQuarters

dtoa	sum, eax		; convert to ASCII characters
output  resultLbl, sum				; output label and sum

mov	 eax, 0			; exit with return code 0
ret
_MainProc ENDP
END								; end of source code

This post has been edited by Wilbur: 14 October 2008 - 11:16 AM

### #7 Wilbur

Reputation: 0
• Posts: 17
• Joined: 26-September 08

## Re: Assembly Language

Posted 14 October 2008 - 11:34 AM

The problem itself is not a difficult concept for me...it is all about the implementation of it in assembly language. Here is the code for this program written in C++. I was able to write this in about 5 minutes.

#include <iostream>
using namespace std;

int main()
{
int pennies = 0;
int nickels = 0;
int dimes = 0;
int quarters = 0;
int dollars = 0;
int totalCents = 0;
int cents;

cout <<"Enter # of pennies: ";
cin >> pennies;
cout <<"Enter # of nickels: ";
cin >> nickels;
cout <<"Enter # of dimes: ";
cin >> dimes;
cout <<"Enter # of quarters: ";
cin >> quarters;

totalCents = pennies + ( nickels * 5 ) + ( dimes * 10 )
+ ( quarters * 25);

dollars = totalCents / 100;
cents = totalCents % 100;

cout << "Total cents: " << totalCents << endl;
cout << "Dollars	: " << dollars << endl;
cout << "Cents		: " << cents << endl;

return 0;
}

I really just don't understand how to do this kind of thing in assembly.

### #8 David W

• DIC supporter

Reputation: 298
• Posts: 1,839
• Joined: 20-September 08

## Re: Assembly Language

Posted 14 October 2008 - 01:49 PM

Quote

I really just don't understand how to do this kind of thing in assembly.

Did you take a look at the HLA code I sent you ... The idea of HLA is to use the High level coding where time is not so critical or to more quickly prototype your scheme ... and get it working and tested ... (And Randy also designed HLA to leverage your knowledge of other languages like C/C++ to fast track your way into Assembly Programming.)

Then if you need to speed some sections up a little, (actually the high level code is all now rewritten in fairly optimized low level code) ... you may be able to shave some time off, by taking each of the HLA structures that you used in HLA and re-coding each, as you wish, in low level. This is a good game plan to attack any program of much size at all. HLA was designed firstly to teach good coding style. Randy Hyde is a real pro at what he does ... The newest versions of HLA are now written in a previous version of HLA.

Shalom,

David

P.S.

This is where most of the real work gets done ...
(I use eax, ebx, and edx; ... eax returns the number of each denomination,
ebx holds a pointer, I need edx:eax to hold 64 bits when I divide a 32 bit number into it ... the quotient is left in eax ... the remainder in edx)

procedure computeCoins( denomination: uns32; var amountLeft: uns32 ); @returns( "eax" );
begin computeCoins;
push( ebx );
push( edx );

mov( amountLeft, ebx ); // ebx holds the address of the value
mov( (type uns32 [ebx]), eax ); // eax now holds the VALUE of amountLeft //*1*//

// 'DIV' divides the 64 bit value in EDX:EAX by the operand
// leaving the quotient in EAX and the remainder in EDX.
// 'div' is used below ...

// Firstly, finish initializing the  'edx:eax' 64 bit 'register' ...
mov( 0, edx );

// int number = amountLeft / denomination;
div( denomination, edx:eax ); // Note that eax was set at //*1*// above
// mov( eax, number ); //Note: eax now holds the quotient i.e. the 'return value'

// and 'update' ... amountLeft = amountLeft % denomination;
mov( edx, (type uns32 [ebx]) ); // amountLeft value returned by ref

pop( edx );
pop( ebx );
// return number
// mov( number, eax ); // eax already holds the 'number'
end computeCoins;

I pass in two values each time ... and two new values returned each time

The denomination, to divide by, was passed in by value, (the default in HLA)
The amount left was passed in and returned by reference ( a 'var' in HLA)
I also returned, via eax, the number of coins for that denomination

That is a BLOCK of code that keeps getting repeated. I can make it a macro, or a procedure, as I wish, in HLA. ( I choose a procedure to allow returning a value in eax, that I hand to a print function each time it is called. That print function first calls for that returned value of eax.)

Or ... I could just write the block and manage all the iterations myself ... but that may be a really bad design choice most of the time.

HLA was designed, among other things, to teach you how your procedures are actually implemented in low level code ... ... so you can do it yourself and you will then know ... if it's really appropriate.

This post has been edited by David W: 14 October 2008 - 02:40 PM

### #9 Wilbur

Reputation: 0
• Posts: 17
• Joined: 26-September 08

## Re: Assembly Language

Posted 15 October 2008 - 02:35 PM

This code will output the number of cents, but only for the quarters.

Example input: pennies = 1. nickels = 1. dimes = 1. quarter = 1.
Example output: 25

.MODEL FLAT

INCLUDE io.h		; header file for input/output

.STACK 4096

.DATA
pennies DWORD   ?
nickels DWORD   ?
nickel DWORD 5
dimes DWORD   ?
dime DWORD 10
quarters DWORD   ?
quarter DWORD 25
numberOfCoins DWORD ?
total DWORD ?
prompt1 BYTE	"How many pennies do you have?", 0
prompt2 BYTE	"How many nickels do you have?", 0
prompt3 BYTE	"How many dimes do you have?", 0
prompt4 BYTE	"How many quarters do you have?", 0
string  BYTE	40 DUP (?)
resultLbl BYTE  "Coin Information", 0
sum	 BYTE	11 DUP (?), 0

.CODE
_MainProc PROC
input   prompt1, string, 40; read ASCII characters
atod	string	; convert to integer
mov	 pennies, eax; store in memory

input   prompt2, string, 40; repeat for second number
atod	string
mov	 nickels, eax

input   prompt3, string, 40; read ASCII characters
atod	string	; convert to integer
mov	 dimes, eax; store in memory

input   prompt4, string, 40; repeat for second number
atod	string
mov	 quarters, eax

mov	 eax, pennies; pennies to EAX
mov		numberOfCoins, eax; numberOfCoins = number of pennies
mov		total, eax; total = pennies

mov		eax, nickels; nickels to EAX
mul		nickel	; multiply numberOfNickels by 5
add		total, eax; total = total + 5*numberOfNickels

mov		eax, dimes; dimes to EAX
mul		dime	; total = total + 10*numberOfDimes

mov		eax, quarters; quarters to EAX
mul		quarter; total = total + 25*numberofQuarters

dtoa	sum, eax					; convert to ASCII characters
output  resultLbl, sum			; output label and sum

mov	 eax, 0	; exit with return code 0
ret
_MainProc ENDP
END						; end of source code

This post has been edited by Wilbur: 15 October 2008 - 07:24 PM