Lab 1 -- Generating assembly code from a higher level language

This is the first Lab, a weekly homework for you to gain experience with class material. These are posted on the official class website (at the https://hallertau.cs.gsu.edu/~mweeks/csc3210 ).

By now, you should be familiar with sftp and ssh, and that you have an account on SNOWBALL. For this assignment, you may* want to upload a file to SNOWBALL (e.g. "sftp snowball.cs.gsu.edu" then "put file1" where "file1" is whatever file you want to upload. We will use a file called "hello.c".).

* The goal is to get a specific file onto the server. You also could accomplish it with the "vi" editor. You should know how to use sftp, however you are not required to use it for this lab.

Next, log in to SNOWBALL (e.g. "ssh your_account@snowball.cs.gsu.edu").

You will create a log file, and demonstrate your ability to complete the lab. The log file is created with the "script" command, and any input or output after that will be stored in the log file, until you give it the "exit" command. Remove any control characters that might be generated from arrow keys, using control-(some key), backspace, etc. In other words, what you turn in should look like what the text on your screen looks like. Upload the log file to iCollege, making sure to use a .txt extension. Do not upload screen-shots.
Hint: You can call the log file "lab1.log", as in the example below. You can use the "cat" command on your log file, and copy and paste its output into a text editor. This should get rid of the control characters. Make sure to save the file as ASCII text. You can use the filename "lab1.txt" for the version of the log file that you turn in. Do not upload files to iCollege without an extension, or with an extension of .log.


First, log in to your account on SNOWBALL. You will probably need to use the command "ssh your_account@snowball.cs.gsu.edu"

cascade:Desktop> ssh snowball.cs.gsu.edu
mweeks@snowball.cs.gsu.edu's password:
Creating home directory for mweeks.
Last login: Mon Dec 4 12:25:41 2023 from 131.96.221.170
+
| GSU Computer Science
| Instructional Server
| SNOWBALL.cs.gsu.edu
+
[mweeks@gsuad.gsu.edu@snowball ~]$ ls
[mweeks@gsuad.gsu.edu@snowball ~]$


Notice that the "ls" command returned nothing. It's a new semester, and any of the old files on this server are gone.

[mweeks@gsuad.gsu.edu@snowball ~]$ vi hello.c

Next, get the "hello.c" file. You can download it from here, or you could copy and paste it from this assignment, or you could even type it yourself. This is a standard, first program for the C language, which you will learn in csc3320. The "vi" editor is a standard Unix text editor, and is a good utility to know about. If you opt to copy and paste (or type) the "hello.c" program, you can use "vi". If you use "sftp" to transfer the file, you do not have to use "vi" for this step.

If you have not started the log, start it now.

[mweeks@gsuad.gsu.edu@snowball ~]$ script lab1.log
Script started, file is lab1.log



Next, we use the "cat" command to display the contents of the "hello.c" file. The "cat" command is short for "concatenate", and can be used to put the contents of multiple files together sequentially. Here, we simply use it to print the contents of a file.

[mweeks@gsuad.gsu.edu@snowball ~]$ cat hello.c


/* 
   hello world
*/

#include <stdio.h>

int main (int argc, char *argv[]) {

   printf("hello world.\n"); 

   return 0;
}


In the next step, we compile the "hello.c" program. "gcc" is the GNU C compiler, and "-o hello" specifies that we want the output to be a new file called "hello". Be careful with this step; if you were to type "-o hello.c", it would over-write the C file, and you would have to start over.
After compiling, we get a list of files with the "ls -l" command. The "-l" option says that we want a long list, i.e. showing details.

[mweeks@gsuad.gsu.edu@snowball ~]$ gcc hello.c -o hello
[mweeks@gsuad.gsu.edu@snowball ~]$ ls -l
total 16
-rwxrwxr-x. 1 mweeks@gsuad.gsu.edu mweeks@gsuad.gsu.edu 8360 Jan 3 10:38 hello
-rw-rw-r--. 1 mweeks@gsuad.gsu.edu mweeks@gsuad.gsu.edu 126 Jan 3 10:37 hello.c
-rw-rw-r--. 1 mweeks@gsuad.gsu.edu mweeks@gsuad.gsu.edu 365 Jan 3 12:27 lab1.log


The file "hello" is executable, and so we run it in the next command. The "./" specifies where to find the file, and "." is short-hand for the current directory.

[mweeks@gsuad.gsu.edu@snowball ~]$ ./hello
hello world.

The program ran as expected, and gave us the line of output. Normally, like in csc3320, you might stop here: so far, we have obtained a C program, showed its contents, compiled it, and ran it. But we're going to go a level deeper.
Next, we will compile it again. Notice the "-S" (and yes, that is a capital S). This generates a new file, "hello.s". We then "cat" its contents, like before.

[mweeks@gsuad.gsu.edu@snowball ~]$ gcc hello.c -S
[mweeks@gsuad.gsu.edu@snowball ~]$ ls
hello hello.c hello.s lab1.log
[mweeks@gsuad.gsu.edu@snowball ~]$ cat hello.s

	.file	"hello.c"
	.section	.rodata
.LC0:
	.string	"hello world."
	.text
	.globl	main
	.type	main, @function
main:
.LFB0:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	subq	$16, %rsp
	movl	%edi, -4(%rbp)
	movq	%rsi, -16(%rbp)
	movl	$.LC0, %edi
	call	puts
	movl	$0, %eax
	leave
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE0:
	.size	main, .-main
	.ident	"GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-44)"
	.section	.note.GNU-stack,"",@progbits


At this point, we now have an assembly-language program. We will get into what the program means. It may look like random text now, but by the end of the semester, you'll be able to explain it to others.

Next, make a copy of it, and call the copy "hello_original.s". It's a good idea to keep copies of files that you change.

After making the copy, edit the "hello.s" file to change the "hello world." text to "Hello World!"

[mweeks@gsuad.gsu.edu@snowball ~]$ cp hello.s hello_original.s
[mweeks@gsuad.gsu.edu@snowball ~]$ vi hello.s

Next, we will use "diff" to show us the difference between the original and new "hello.s" files.

[mweeks@gsuad.gsu.edu@snowball ~]$ diff hello_original.s hello.s
4c4
< .string "hello world."
---
> .string "Hello World!"


As you can see, only the string should be changed.

Next, we use "gcc" to create an object file called "hello.o". An object file is created before linking produces the executable file. Notice the "-c" argument that is passed to "gcc". Also notice how the second "ls" output shows the new file "hello.o".

[mweeks@gsuad.gsu.edu@snowball ~]$ ls
hello hello.c hello_original.s hello.s lab1.log


For the next step, we will use the object file to create an executable file. Again, we use "gcc" for this. Notice the "-o" argument that is passed to "gcc". The output file that this command creates is called "hello2".

[mweeks@gsuad.gsu.edu@snowball ~]$ gcc -c hello.s
[mweeks@gsuad.gsu.edu@snowball ~]$ ls
hello hello.c hello.o hello_original.s hello.s lab1.log
[mweeks@gsuad.gsu.edu@snowball ~]$ gcc hello.o -o hello2
[mweeks@gsuad.gsu.edu@snowball ~]$ ls
hello hello2 hello.c hello.o hello_original.s hello.s lab1.log


Now we run the executable program.

[mweeks@gsuad.gsu.edu@snowball ~]$ ./hello2
Hello World!


The "-v" option for "gcc" means "verbose". The next command produces the same results as "gcc -c hello.s" does, but it generates a lot of additional information. One thing worth pointing out is that the target is "x86_64-redhat-linux", a 64 bit Intel x86 processor. We are not likely to need the "-v" option normally, but if there is a problem, this may reveal what the problem is.

[mweeks@gsuad.gsu.edu@snowball ~]$ gcc -v -c hello.s
Using built-in specs.
COLLECT_GCC=gcc
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
COLLECT_GCC_OPTIONS='-v' '-c' '-mtune=generic' '-march=x86-64'
as -v --64 -o hello.o hello.s
GNU assembler version 2.27 (x86_64-redhat-linux) using BFD version version 2.27-44.base.el7_9.1
COMPILER_PATH=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/:/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/:/usr/libexec/gcc/x86_64-redhat-linux/:/usr/lib/gcc/x86_64-redhat-linux/4.8.5/:/usr/lib/gcc/x86_64-redhat-linux/
LIBRARY_PATH=/usr/lib/gcc/x86_64-redhat-linux/4.8.5/:/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-c' '-mtune=generic' '-march=x86-64'


Next, run the original "hello" program. Then run the "hello2" program that we created from an altered assembly language listing.

[mweeks@gsuad.gsu.edu@snowball ~]$ ./hello
hello world.
[mweeks@gsuad.gsu.edu@snowball ~]$ ./hello2
Hello World!


Finally, we exit from the script command. This informs the "script" utility that we are done.

[mweeks@gsuad.gsu.edu@snowball ~]$ exit
exit
Script done, file is lab1.log



You might want to next use "cat" on the "lab1.log" file, copy the output, and paste it into a text file called "lab1.txt". This should get rid of any extraneous (control) characters, though you should look it over to make sure. There are other ways to do this: one would be to make your own filtering program, that only allows characters with ASCII values 32 to 126, along with the newline (linefeed) character (10). Tab, character 9, might be useful too, maybe mapped to 4 spaces.

Then we exit (log out) from the server. You can use "sftp" to get your log file from the server.

[mweeks@gsuad.gsu.edu@snowball ~]$ exit
logout
Connection to snowball.cs.gsu.edu closed.
cascade:Decktop>

In this lab, we have: