Difference between revisions of "CSC231 Lab 5 2010"
(→Ingrendient #2: A Mini Library in Assembly) |
(→Ingredient #3: Your Assembly Program that uses the new Library) |
||
Line 136: | Line 136: | ||
** The '''asm_io''' library supports also two ''macros'' that you may find useful: ''dump_regs'' and ''dump_mem''. They can be used to display the contents of the registers and the contents of memory. Try adding these two lines at the end of your '''hw5test.asm''' program: | ** The '''asm_io''' library supports also two ''macros'' that you may find useful: ''dump_regs'' and ''dump_mem''. They can be used to display the contents of the registers and the contents of memory. Try adding these two lines at the end of your '''hw5test.asm''' program: | ||
+ | |||
call print_nl ; call the function that prints | call print_nl ; call the function that prints | ||
; a new blank line | ; a new blank line | ||
− | + | ||
− | dump_regs 1 | + | dump_regs 1 ; display registers, and use marker "1" |
− | dump_mem 1, msg, 3 | + | dump_mem 1, msg, 3 ; display variable 'msg', mark it as "1" |
− | + | ; and display 3 bytes | |
;; return to C program | ;; return to C program |
Revision as of 09:31, 22 October 2010
--D. Thiebaut 23:12, 20 October 2010 (UTC)
--D. Thiebaut 14:12, 22 October 2010 (UTC)
Contents
This lab is in preparation for the current homework assignment due 10/28. It shows you the steps necessary for mixing C and assembly programs together.
Preparation For Homework 5
Important Note: this problem must be done on grendel.csc.smith.edu, as it requires a 32-bit machine, while beowulf is a 64-bit machine. This has to do with mixing assembly (generated in 32-bit mode) and C-programs (compiled in 64-bit on beowulf, and in 32-bit on grendel).
While printing strings of characters on the screen is relatively easy in assembly, as you saw in the previous assignment and exercises, inputing numbers and printing numbers is more difficult in assembly (we'll see why in class later).
So, for the time being, to deal with the input/output of integers we will use a trick: we will link our assembly language program to a C program, and make the C program handle the input and output of information for us.
Don't worry if you don't know C. We will not write a single line of C code except for the small C program which will never change.
When we want to print a number from our assembly program, or when we want to get a number from the keyboard, we simply call the appropriate C function from our assembly program. Because the linker will link our program with the C program, we can call functions written in another language from assembly. This is a useful programming trick!
It sounds complicated, but you'll see that it isn't that bad.
Ingredient #1: A C Program
- Let's try this concept with a simple example:
- First use your favorite editor to write the following C program and call it driver.c
#include <stdio.h> extern int asm_main( void ); int main() { asm_main(); }
- All it does is have a main program that calls a function asm_main(), which will be the entry point of our assembly language program.
Ingrendient #2: A Mini Library in Assembly
- Next get a small library that will provide a simple interface between this C program and our assembly language program.
- Create the object file for the library:
nasm -f elf -F stabs asm_io.asm
Ingredient #3: Your Assembly Program that uses the new Library
- Now enter the test program below in assembly. Call it hw5test.asm. Be careful that it is slightly different from the ones we have been writing so far in that the starting label and the last instructions are not the standard ones.
;;; hw5test.asm ;;; a simple demo program to test I/O with ;;; a C "wrapper" program %include "asm_io.inc" ;; ------------------------- ;; data segment ;; ------------------------- section .data msg db "Hello! Please enter an integer number: ",0x00 msg2 db "You have entered ",0x00 x dd 0 ;; ------------------------- ;; code area ;; ------------------------- section .text global asm_main asm_main: mov eax,msg ; pass address of the string msg in eax call print_string ; call a function in asm_io library ; that will print the string msg call read_int ; call a function that reads an mov [x], eax ; integer from the keyboard and ; returns it in eax. Save returned ; value in variable x mov eax,msg2 ; print the string msg2 call print_string ; ("you have entered") mov eax,[x] ; get integer user entered call print_int ; pass it via eax and call the ; function specialized in printing ; integer numbers call print_nl ; call the function that prints ; a new blank line ;; return to C program ret
- To assemble and run your program just follow these steps:
nasm -f elf -F stabs hw5test.asm gcc -o hw5test driver.c asm_io.o hw5test.o ./hw5test Hello! Please enter an integer number: 1234 You have entered 1234
- The first line assembles hw5test.asm. The second line asks the C compiler gcc to compile driver.c and to link it with the object files asm_io.o and hw2test.o, and to store the executable in a file called hw5test. The last line executes the program.
- The functions provided by the asm_io.o library are described now:
- read_int: reads an integer from the keyboard and stores it into the EAX register.
- print_int: prints out in 2's complement the value of the integer stored in EAX on the screen.
- print_string: prints out to the screen the contents of the string at the address stored in EAX. The string must be terminated by a 0x00 byte (C-string).
- print_char: prints out to the screen the character whose ASCII value is stored in AL
- read_char: reads a single character from the keyboard and stores its ASCII code into the EAX register.
- print_nl: prints out to the screen a new line character.
- The asm_io library supports also two macros that you may find useful: dump_regs and dump_mem. They can be used to display the contents of the registers and the contents of memory. Try adding these two lines at the end of your hw5test.asm program:
- read_int: reads an integer from the keyboard and stores it into the EAX register.
call print_nl ; call the function that prints ; a new blank line
dump_regs 1 ; display registers, and use marker "1" dump_mem 1, msg, 3 ; display variable 'msg', mark it as "1" ; and display 3 bytes ;; return to C program ret
- The first of the new lines dump_regs 1 dumps the registers and uses 1 as a label, so that if you use this macro several times in your program, you can label each one with a different number so that you can figure out from the output which macro actually output what. The second of the new lines dump_mem 1, msg, 3 output 3 lines of 16 bytes starting at the address corresponding to the variable msg, and uses 1 as the label for this output.