Jan 23, 2012

Making Decision (if Statement)

Up until now, we have been writing a program that executes the statements one by one until the defined end. The functionality of this type of program is limited since it flows in single direction. Now we will be looking at one of the most powerful programming feature - the ability to change the flow of program execution. It is achieved by establishing the truth or falsity of an expression (condition).

Consider the following program.

#include<stdio.h>

int main()
{
   int V;
   printf("Enter the value of voltage, V: ");
   scanf("%d", &V);
   printf("The value of V is %d\n", V);
   return 0;
}

The program prints the value of V which is inputted by the users. What if we want the program prints V when the users enter a value that is more than 5 only. This means, the program has to be able to make a decision based on the user's input. C provides a decision making capability in the form of if statement. if is used when we want statements to be executed if an expression is TRUE. Otherwise the statements are skipped. Now, lets add an if statement to the above program as follows.

#include<stdio.h>

int main()
{
   int V;
   printf("Enter the value of voltage, V: ");
   scanf("%d", &V);
   if(V > 5)
      printf("The value of V is %d\n", V);
   return 0;
}

Output
Enter the value of voltage, V: 8
The value of V is 8


if(V > 5)
   printf("The value of V is %d\n", V);

V is compared with 5. If the value of V is greater than 5, the printf() statement will be executed which prints a string on the monitor. Otherwise the printf() will be skipped. In the example, 8 is entered by the user, thus "The value of V is 8" is displayed.

Relational & Logical Operators


Relational operators are used to compare two values. There are six (6) operators as listed in the following table.

Operator Meaning
==
Equal to
!=
Not equal to
<
Less than
<=
Less than or equal to
>
Greater than
>=
Greater than or equal to

Relational operators have lower precedence than arithmetic operators. For example, consider the following expression.

x + y > z

Since arithmetic operators precede relational operators. The expression is evaluated as

(x + y) > z

Assumes that x, y and z is 2, 3 and 4. Then, the expression is said TRUE. An expression is TRUE if it satisfies the condition and FALSE otherwise. In C, TRUE has the value of 1 while FALSE has the value of 0.

There are three (3) logical operators which are AND (&&), OR (||) and NOT (!). More than one expression can be combined using AND (&&) and OR (||) operators. For example, consider the following expression.

a > b && x == y

If both a > b and x == y are TRUE, the expression returns,

1 && 1

which will returns 1 (TRUE).

! is used to invert the logical value of an expression. For example,

!(x > 2)

Assume that x is 3 then the expression is said to be FALSE.

Jan 15, 2012

Program Input

Consider this program.

#include<stdio.h>

int main()
{
   int V;
   V = 15;
   printf("The value of V is %d\n", V);
   return 0;
}

The value of V is assigned with 15. Thus the printed text will be "The value of V is 15". Now, what if we want to print different value of V. We have to go back to the source code and change 15 to the desired value. And what if we want the value to be set during the program execution. For example, the program might ask a value which the user wants to print. Such operation can be effected by using a function called scanf. The scanf function is the opposite of printf function. While printf prints values at the terminal, scanf reads values entered by users into the program. The following program prints a message which asking the user to enter a value of V.

#include<stdio.h>

int main()
{
   int V;
   printf("Enter the value of voltage, V: ");
   scanf("%d", &V);
   printf("The value of V is %d\n", V);
   return 0;
}

Output
Enter the value of voltage, V: 5
The value of V is 5


The first printf prints "Enter the value of voltage, V: ". This message prompts the user to type in a value for voltage. Then scanf function is invoked. The scanf contains two arguments. The first argument is the format control string specifies the data type of value to be read from the terminal. In this example %d is specified which indicates integer value is expected to be read. The second argument specifies which variable to be used to store the inputted value. The ampersand (&) is necessary in this case. The function of & will be explained later. For now don't forget to put leading & in front of the variable when using scanf function.

As explained in the preceding discussion, integer value is to be read from the terminal and stored in V. 5 is type in as given in the example. Thus, 5 is printed by the subsequent printf function and then the program execution is complete.

Jan 14, 2012

Arithmetic Expression

Basic arithmetic expression such as addition, subtraction, multiplication and division can be written in C by using following signs:
  • plus (+)
  • minus (-)
  • asterisk (*)
  • slash (/)

For example,

#include<stdio.h>

int main()
{
   int n1, n2, n3;
   n1 = 4;
   n2 = 2;
   n3 = n1 + n2;
   printf("n3 is %d\n", n3);

   n3 = n1 - n2;
   printf("n3 is %d\n", n3);

   n3 = n1 * n2;
   printf("n3 is %d\n", n3);

   n3 = n1 / n2;
   printf("n3 is %d\n", n3);

   return 0;
}

2 and 4 are assigned to n1 and n2. n3 is assigned with the result of adding n1 with n2. The next arithmetic is subtracting n2 from n1 and the result is stored in n3. Statement

n3 = n1 * n2;

introduces multiplication operator and storing the result in n3. The last arithmetic statement reads,

n3 = n1 / n2;

n1 is divided with n2 and the result (quotient) is stored in n3. Remainder of a division operation can be obtained by using modulus operator which is denoted by percent (%) sign. For example,

   ...
   n1 = 5;
   n2 = 2;

   n3 = n1 % n2;
   printf("n3 is %d\n", n3);
   ...

The value of n3 is 1.

Jan 3, 2012

Subroutine

Introduction
Subroutine is a set of instructions within a large program that perform a specific task. Subroutine is coded such that it can be invoked repeatedly from anywhere in the program including other subroutines, and then returns and continues the execution at the next instruction after the invoke instruction. The sequence of execution involving subroutine is illustrated in Figure 1.


Instructions to call a subroutine are bsr (branch subroutine) and jsr (jump subroutine). When bsr and jsr instructions are executed, the return address is saved in the stack and stack pointer (SP) is decremented by 2. Bothbsr and jsr, the operand is specified by using a label (relative addressing mode). The label specify the location of the subroutine in the program. In addition to relative addressing mode, operand of jsr instruction can be specified by using direct, extended, indexed and indexed indirect addressing modes. Program control returns to the main program by using rts. Return address is pop from the stack onto the PC and increment the SP by 2. Program execution continues at the address restored from the stack.

There are issues that require consideration when implementing subroutines.
  1. Passing parameters
  2. Returning results
  3. Saving CPU registers
  4. Local variables

Parameter Passing and Results Returning
Subroutine might requires values from main program (caller) for its computation. Results of the computation might need to be returned to the main program. In fact, it is a common practice to write a subroutine with a specific purpose of computing one or more results whose values are determined by the parameters passed by the caller. Passing parameters may be implemented by using CPU registers, the stack or defining global memories. Parameters are pushed into the stack for example before the subroutine is called. Similar operation is performed when returning results to the main program. The results are placed in CPU registers before the subroutine complete its execution.

Saving CPU Registers
Subroutine may use CPU registers to hold values for its computation. However the values it the CPU registers may also be used by the caller. If the values are not preserved when a subroutine is called, the result computation of the caller will be incorrect. Therefore the CPU registers must be saved before a subroutine is executed. Either the caller or subroutine is responsible for saving the registers. Stack is used to save the registers.

Local Variables
Subroutine may require memory locations to hold temporary values for its computation. These memory locations are available and accessible by the subroutine thus it is called local variables. Allocating local variables are done by using leas instruction. To allocate n local variables, the instruction is written as

leas -n,SP

SP is the base register which hold the base address and n is the offset. Before subroutine complete its execution, the local variables are deallocated.

leas n,SP


The following program shows an example of program with a subroutine.


i     equ    0
c     equ    1
N     equ    2
      org    $1510
arr1  dc.b   $11,$22,$33,$44
      org    $1530
arr2  dc.b   $55,$66,$77,$88,$99,$AA

      org    $2000
      lds    #$2000
      ldx    #arr1 ; parameter passing (index register X)
      ldaa   #4 ; parameter passing (accumulator B)
      jsr    tb7 ; call subroutine tb7

      ldx    #arr2
      ldaa   #6
      jsr    testb7
      ...
      swi

; Subroutine begin
tb7   leas   -3,sp ; allocate 3 local variables
      clr    c,sp ; init c
      clr    i,sp ; init i
      staa   N,sp ; init N/get value of N
loop  ldab   i,sp
      cmpb   N,sp
      beq    exit
      ldaa   b,x
      bita   #$80 ; test bit 7 for zero
      bne    skip ; tested bit 7 are not zero, don't count (skip)
      inc    c,sp
skip  inc    i,sp
      bra    loop
exit  ldab   c,sp ; result returning (accumulator B)
      leas   3,sp ; deallocate local variables
      rts;     ; return to main program
; Subroutine end
      end

Index register X and accumulator A are used for parameter passing while accumulator B is used to return the result to the caller. Three local variables are allocated by the subroutine.