# Lab 2: User Input and Arithmetic

## Overview

Your company is programming an embedded device that can manually adjust the settings of laboratory equipment. The technicians will type in a value using a terminal and then receive an output depending on how the machine responds.

You will learn about user input and basic calculations in NASM.

### Registers and Pointers

Recall in C that you can work with the value directly or work with a value at a specific memory location.

• `&` gets the address of the variable.

• `*` get the value of the variable at the memory location.

Consider this code block:

```int x = 5;              // Assign x to a value

printf("Value of 'x':       = %d; \n", x);

/*
Output:
Value of 'x':       = 5;
*/
```

ASM operates in a similar way. See slides 22 and 24 in Introduction to NASM Programming.

```mov  eax, 5      ; places the value of 5 in register EAX
; eax = 5

mov  ecx, [eax]  ; places the contents at the address of EAX in ECX
; ecx = *eax
```

### Reserving Memory

The programmer is responsible for reserving to prevent a segmentation fault and other errors. There are two types of data directives in an ASM file to reserve memory, which `DX` and `RESX`.

The `X` refers to the data size.

DX/RESX Data Unit

Unit

Letter (X)

Size in bytes

byte

b

1

word

w

2

double word

d

4

q

8

ten bytes

t

10

DX directives: Initialized Data (D = “defined”)

Memory is reserved in the DX block using the three elements:

1. label - An unquoted text string

2. `d` + memory unit

3. initial value

DX Examples
```L1    db    0x55                ; just the byte 0x55
L2    db    0x55,0x56,0x57      ; three bytes in succession
L3    db    'a',0x55            ; character constants are OK
L4    db    'hello',13,10,'\$'   ; so are string constants
L5    dw    0x1234              ; 0x34 0x12
L6    dw    'a'                 ; 0x61 0x00 (it's just a number)
L7    dw    'ab'                ; 0x61 0x62 (character constant)
L8    dw    'abc'               ; 0x61 0x62 0x63 0x00 (string)
L9    dd    0x12345678          ; 0x78 0x56 0x34 0x12
L10   dd    1.234567e20         ; floating-point constant
L11   dq    0x123456789abcdef0  ; eight byte constant
L12   dq    1.234567e20         ; double-precision float
L13   dt    1.234567e20         ; extended-precision float
```

RESX directives: Uninitialized Data (RES = “reserved”)

Memory is reserved in the RESX block using the three elements:

1. label - An unquoted text string

2. `res` + memory unit

3. memory to reserve

RESX Examples
```buffer:       resb    64        ; reserve 64 bytes
wordvar:      resw    1         ; reserve a word
realarray:    resq    10        ; array of ten reals (floats)
```

1. Create your project directory, `input.asm` file, and `Makefile`.

Tip

Create a template folder that you can replicate for each project.

```# Create a copy for a new project
cd ~/asm
cp -r template lab2
```

## Task 2: Prompt for Input and Print the values

You will verify that your program can read in a value and display it.

Use Introduction to NASM Programming and NASM: data and bss (inverted) to help you.

1. Display a message to the user to input a value. The string to print goes in the `.data` segment.

2. Read the input using `read_int`, which get put in register EAX.

```call    read_int     ; read_int puts the value in EAX
```
3. Print the value using `print_int`

Expected Output
```Enter a value: 358
358
```

Note

The value resides in EAX, but we will lose the value if we don’t store it in memory.

4. Create a label for the input value in the `.bss` segment and reserve memory for a 32-bit value, which is 4 bytes or a `double word`.

• Call the label `VAL1`

• Choose a method to reserve 32 bits

```VAL1    resd    1  ; reserve a single double word
VAL1    resb    4  ; reserve 4 bytes
```
5. Store the value in EAX in memory using the address at VAL1.

Note

This operation works with the memory address, similar to how C uses a pointer with `scanf`.

```char *input;          // Get pointer to a single byte
scanf("%s",&input);   // Read a single byte and store in memory
```

You would do this in ASM:

```mov    [VAL1], eax
```
6. Prompt the user for a second value and store it in memory using a label called `VAL2`.

7. Print the first value that label `VAL1` references. You must first move the value to EAX.

```mov    eax, [VAL1]
```
8. Verify that you can input and output the full range of signed 32-bit values. Then, try entering more data than can fit in a 32-bit register (EAX).

Expected Output
```; Minimum range
Enter a value: 1
Enter a value: -1
1
-1

; Maximum range
Enter a value: 2147483647
Enter a value: -2147483648
2147483647
-2147483648

; Values too large for the register are truncated
Enter a value: 9999999999
Enter a value: -9999999999
2147483647
-2147483648
```

Your program now accepts user input, stores the value in memory, and then prints the value to the screen.

It more interesting to do something with the data instead of reprinting the input.

Tip

• Move the data to a register to manipulate it.

• Use registers `EAX`, `ECX`, and `EDX` for general use or scratch registers.

Here is a quick list of use NASM commands for manipulating data.

Quick List (useful commands)

Command

Stored Result

mov x, y

x ← y

and x, y

x ← x and y

or x, y

x ← x or y

xor x, y

x ← x xor y

x ← x + y

sub x, y

x ← x – y

inc x

x ← x + 1

dec x

x ← x – 1

1. Move the value in `VAL1` to ECX.

2. Move the value in `VAL2` to EDX.

3. Increment the first input placed in ECX.

4. Decrement the second input placed in EDX.

5. Print the results.

Note

You will have to move the values to EAX to print them

```Enter a value: 10
Enter a value: 20
10       ; [VAL1]
20       ; [VAL2]

11       ; [VAL1]++
19       ; [VAL2]--
```
6. Add the two values together and store the value in `RESX` with a label of `RESULT`.

7. Print the value in `RESULT`.

Expected Results
```Enter a value: 10
Enter a value: 20
10       ; [VAL1]
20       ; [VAL2]

11       ; [VAL1]++
19       ; [VAL2]--

30       ; [RESULT] = [VAL1] + [VAL2]
```
8. Subtract `VAL1` or `VAL2` from `RESULT` and verify that value matches the original. You can call `dump_regs 0` to view the contents of the registers.

Expected Results
```Enter a value: 10
Enter a value: 20
10       ; [VAL1]
20       ; [VAL2]

11       ; [VAL1]++
19       ; [VAL2]--

30       ; [RESULT] = [VAL1] + [VAL2]

11       ; [RESULT] = [RESULT] - [VAL2]

Register Dump # 0
EAX = 0000000B EBX = 56649FCC ECX = 0000000B EDX = 00000013
ESI = F7FAF000 EDI = 00000000 EBP = FFD870C8 ESP = FFD870A8
EIP = 56648851 FLAGS = 0202
```

## Task 4: Multiplication and Division

You should have a good feel for working with registers and RESX directives. Now, we can do more complex operations by performing multiplication and division.

Note

• Take note of the specific registers in the table.

• The operations stores the result in register `EAX`, but use register `EDX` to store additional data.

Quick List (Multiplication and Division)

Command

Stored Result

Notes

`mul eax`

eax ← eax * eax
edx ← higher

• Lower results go in EAX.

• Higher results go in EDX.

`mul x`

eax ← eax * x

• Multiplies EAX with the value in the other register.

• Uses register EDX if the Carry Flag is set.

`div ecx`

eax ← eax / ecx
edx ← remainder

Divides EAX by the value in the register by EAX.
You must clear EDX before the operation.

Note

You should clear register EDX before performing a multiplication or division operation.

1. Multiply the value in EAX by the value in `VAL1` and print the results.

Note: You need to put `VAL1` in register ECX.

Expected Results
```Enter a value: 10
Enter a value: 20
10       ; [VAL1]
20       ; [VAL2]

11       ; [VAL1]++
19       ; [VAL2]--

30       ; [RESULT] = [VAL1] + [VAL2]

11       ; [RESULT] = [RESULT] - [VAL2]

110      ; [RESULT] = EAX * [VAL1]

Register Dump # 0
EAX = 0000006E EBX = 56580FCC ECX = 0000000A EDX = 00000000
ESI = F7EC7000 EDI = 00000000 EBP = FFBB11E8 ESP = FFBB11C8
EIP = 5657F878 FLAGS = 0202
```
2. Now, divide the value in EAX by the value in `VAL2`. Print the result of the division (EAX) and of the remainder (EDX).

`110 / 20 = 5, remainder 10`

Note

Evaluate the results of `dump_regs` to see the parts equation and result.

Expected Results
```Enter a value: 10
Enter a value: 20
10       ; [VAL1]
20       ; [VAL2]

11       ; [VAL1]++
19       ; [VAL2] --

30       ; [RESULT] = [VAL1] + [VAL2]

11       ; [RESULT] = [RESULT] - [VAL2]

110      ; EAX = EAX * [VAL1]

5        ; EAX = EAX / [VAL2]
10       ; Remainder in EDX

Register Dump # 0
EAX = 0000000A EBX = 5660DFCC ECX = 00000014 EDX = 0000000A
ESI = F7F25000 EDI = 00000000 EBP = FF9939A8 ESP = FF993988
EIP = 5660C89B FLAGS = 0202
```