Tag Archives: assembly

Assembly || How To Obtain & Display Integer Data

Displaying text to the screen was discussed in the previous article, and this page will be more of the same. Utilizing the printf and scanf functions which are available in C, this page will demonstrate how to obtain and display integer data; and more importantly, demonstrate how to store a 64-bit integer into an assembly program.

==== Obtain & Display Integer Data ====

Here is our driver.c file, which starts things off.

The “driver” file really only has one task, and that is simply to call the assembly function named ‘DisplayNum()’ as noted on line 38. This is a routine that is present among all the code on this site. Click here for an explanation on why a “driver” is used.

And here is the assembly file.


QUICK NOTES:
The highlighted lines are sections of interest to look out for.

The text declarations highlighted under the segment .data section are important, particularly the variable named “unsignedLongIntegerInput.” That variable is used to obtain data from the user, as noted on line 74-77. Note, that this same variable is also used to display the integer data back to the user, which is also displayed on lines 86-89.

The rest of the code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.

After you assemble the above code (see below), you should get this as your output:

Welcome to My Programming Notes' Assembly Program.

Control will now be passed to the Assembly file...

--------------------------------------------
Please enter a number: 1858
The number you just entered is: 1858
--------------------------------------------

Control has now been passed back from the Assembly file to the C file!

The return code is: 0

BYE!

==== ASSEMBLING THE CODE ====

This can be achieved by simply opening the teminal, and doing a copy/paste of the commands listed on the ‘driver.c’ file, lines 15 thru 18. Make sure to compile them in order for the sake of continuity.


Be advised, that the commands to assemble the code is designed to run in 64-bit mode. If you are not running a 64-bit machine, the commands will most likely fail to assemble.

If you are running a Windows computer and would like to assemble the code, look here or here for information.

You will need to change the 64-bit registers to 32-bit registers in the “displayNum.asm” file, aswell as removing lines 41-55 and lines 106-120 respectively in order to run the program successfully.

Assembly || Hello World!

This page will consist of creating the typical “hello world!” application. if you have never programmed in assembly before, this will be very interesting as the syntax is very different from most high level programming languages.

As noted on the introductory page, the assembly code presented on this site (X86-64) was assembled using The Netwide Assembler (NASM) under the Unix platform (Ubuntu) in association with C/C++ files. The purpose of combining Assembly code in association with C/C++ files is to demonstrate how each language “talks” to each other. Also, more importantly it is because today, it is unusual to create a stand alone program written completely in assembly language. Why is that the case? Because It is much easier and faster to program in a high level language than it is in assembly. So why should you learn assembly? Learning assembly can be most useful to help one gain a deeper understanding of how computers work, aswell as helping one to better understand how compilers and higher level languages like C work.

==== HELLO WORLD ====

All of the programs presented on this site will start with a simple C or C++ driver program like so:

The “driver” file really only has one task, and that is simply to call the assembly function named ‘DisplayHelloWorld()’ as noted on line 39. This is a routine that will be present among all the code on this site.

There are several advantages in using the C driver routine. First, this lets the C system set up the program to run correctly in protected mode. All the segments and their corresponding segment registers will be initialized by C. The assembly code doesn’t need to worry about any of this. Secondly, the C library will also be available to be used by the assembly code.

The following shows a simple assembly program utilizing the C function “printf” to display ‘Hello World’ to the screen.


Line 16 of the program defines a section that specifies memory to be stored in the data segment (whose name is .data). Only initialized data should be defined in this segment. On lines 19 to 21, several strings are declared. They will be printed with the C library, so they must be terminated with a null character (ASCII code 0). Remember there is a big difference between 0 and ’0’. Note, the number 10 is the ASCII code for a newline.

Uninitialized data should be declared in the .bss segment (named .bss on line 25). This segment gets its name from an early UNIX-based assembler operator that meant “block started by symbol.”

The code segment named .text is where instructions are placed. Note that if you are using Windows, the code label for the main routine (line 29 and 33) should have an underscore prefix, so it would be _DisplayHelloWorld. You would also need to do the same for printf (so it would be _printf). This is part of the C calling convention. This convention specifies the rules C uses when compiling code. It is very important to know this convention when interfacing C and assembly. (Note: This rule is specifically for DOS/Windows, the Linux C compiler does not prepend anything to C symbol names.)

The global directive on line 29 tells the assembler to make the asm main label global. Unlike in C, labels have internal scope by default. This means that only code in the same module can use the label. The global directive gives the specified label (or labels) external scope.

And there you have it! After you assemble the above code (see below), you should get this as your output

Welcome to My Programming Notes' Assembly Program.

Control will now be passed to the Assembly file...

--------------------------------------------
Hello World!
--------------------------------------------

Control has now been passed back from the Assembly file to the C file!

The return code is: 0

BYE!

==== ASSEMBLING THE CODE ====

This can be achieved by simply opening the teminal, and doing a copy/paste of the commands listed on the ‘driver.c’ file, lines 16 thru 19. Make sure to compile them in order for the sake of continuity.


Be advised, that the commands to assemble the code is designed to run in 64-bit mode. If you are not running a 64-bit machine, the commands will most likely fail to assemble.

If you are running a Windows computer and would like to assemble the code, look here or here for information.

You will need to change the 64-bit registers to 32-bit registers in the “helloWorld.asm” file, aswell as removing lines 38-52 and lines 80-94 respectively in order to run the program successfully.

Assembly || Which Assembler To Use?

A common question one may wonder is, which assembler should I use? There are a few choices, and your choice should probably be based on the type of platform you decide to operate with.

In terms of Assembly, there is a whole family of languages each specific to a different processor, and each language has several different names for a single language. These are the following designations which are often seen: IA-32, X86-32, X86-i386, 80×86, X86, X86-16, IA-64, X86-64, and so on. Some of those early languages are now obsolete. The extension of Assembly which will be presented on this site is the x86 instruction set, specifically being X86-64 (which is known as IA-64 in some documents). The X86-64 Assembly code will be assembled using the Unix platform (Ubuntu) in association with C/C++ files, demonstrating how each language “talks” to each other.

As far as which assembler to use, there are a few high level ones which are available to choose from. Some high level assemblers are Borland’s TASM, The Netwide Assembler’s NASM, Microsoft’s MASM, IBM’s HLASM (for z/Architecture systems), Alessandro Ghignola’s Linoleum, and Niklaus Wirth’s PL/360.

Of the assemblers listed above, The Netwide Assembler (NASM) is the recommended choice, as it is open source and free of charge. The Microsoft Macro Assembler (MASM), and The Borland Company’s Turbo Assembler (TASM) can also be used to learn Assembly Language. You may use other assemblers if you wish, though it is not guaranteed that the code presented on this site will work for assemblers other than NASM.

==== INSTALLING NASM ====

– On Windows –

(1) Visit the NASM homepage, and click on the tab which says "Downloads"

(2) Click on the link to the most current version of NASM, downloading the most recent archive for NASM (the zip file) located under the "win32" directory

(3) Once you've obtained the appropriate archive for NASM, nasm-XXX-dos.zip or nasm-XXX-win32.zip (where XXX denotes the version number of NASM contained in the archive), unpack it into its own directory (for example c:nasm).

Note: You can alternatively download the installer file located in the "win32" directory which will install NASM for you, forgoing the remaining steps.

(4) The archive will contain a set of executable files: the NASM executable file nasm.exe, the NDISASM executable file ndisasm.exe, and possibly additional utilities to handle the RDOFF file format.

(5) The only file NASM needs to run is its own executable, so copy nasm.exe to a directory on your PATH, or alternatively edit autoexec.bat to add the nasm directory to your PATH (to do that under Windows XP, go to Start > Control Panel > System > Advanced > Environment Variables; these instructions may work under other versions of Windows as well.)

(6) That's it - NASM is installed. You don't need the nasm directory to be present to run NASM (unless you've added it to your PATH), so you can delete it if you need to save space; however, you may want to keep the documentation or test programs.

– On Ubuntu –

NASM is currently located in the Ubuntu repository, so you can install it by simply opening the terminal window and entering the command:


sudo apt-get install nasm

– On Other Versions Of Unix –

(1) Visit the NASM homepage, and click on the tab which says "Downloads"

(2) Once you've obtained the Unix source archive for NASM, nasm-XXX.tar.gz (where XXX denotes the version number of NASM contained in the archive), unpack it into a directory such as /usr/local/src. The archive, when unpacked, will create its own subdirectory nasm-XXX.

(3) NASM is an auto-configuring package: once you've unpacked it, cd to the directory it's been unpacked into and type ./configure. This shell script will find the best C compiler to use for building NASM and set up Makefiles accordingly.

(4) Once NASM has auto-configured, you can type make to build the nasm and ndisasm binaries, and then make install to install them in /usr/local/bin and install the man pages nasm.1 and ndisasm.1 in /usr/local/man/man1. Alternatively, you can give options such as --prefix to the configure script (see the file INSTALL for more details), or install the programs yourself.

(5) NASM also comes with a set of utilities for handling the RDOFF custom object-file format, which are in the rdoff subdirectory of the NASM archive. You can build these with make rdf and install them with make rdf_install, if you want them.

Note: Instructions for installing NASM was taken from the official website located here. If you need further assistance installing NASM onto your computer, check out the help forums.