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:
- logged into a remote server
- produced assembly language code from a .c file
- changed the assembly language file to produce
different results
- verified the changes in the file with the "diff" command
- compiled an assembly language file to an executable
- ran the executable program