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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
// ========================================================================================================== // Author: K Perkins // Date: Jul 12, 2012 // Program: Display A Number // Taken From: http://programmingnotes.org/ // File: driver.c // // Purpose: This is the driver to the "Display A Number" program. Driver.c only calls displayNum.asm. This // file is used just as a "driver" and demostrates how to use a C file along with an Assembly file to // create one working program. Once the Assembly file finishes, control of the program is then passed back // to the driver.c file, then the program closes // // ----- These are the commands to link all the files together ------- // // (1) Compile driver.c file: gcc -c -Wall -m64 -std=c99 -l driver.lis -o driver.o driver.c // (2) displayNum.asm assembler file: nasm -f elf64 -l displayNum.lis -o displayNum.o displayNum.asm // (3) Link all files: gcc -m64 -o displayNum.out driver.o displayNum.o // (4) Execute in 64-bit protected mode: ./displayNum.out // // ===== Begin code area ==================================================================================== #include <stdio.h> // external function prototype extern unsigned long int DisplayNum(); int main() { // declare variable unsigned long int returnCode = 1987; // display message to the screen printf("nnWelcome to My Programming Notes' Assembly Program.n"); printf("nControl will now be passed to the Assembly file...nn"); // here is a function call to the assembly file, where the asm file passes // back a return code to this current file, which will be displayed below returnCode = DisplayNum(); printf("nControl has now been passed back from the Assembly file to the C file!n"); printf("nThe return code is: %lu", returnCode); printf("nnBYE!n"); return returnCode; }// http://programmingnotes.org/ |
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
;================================================================================================================ ; Author: K Perkins ; Date: Jul 12, 2012 ; Program: Display A Number ; Taken From: http://programmingnotes.org/ ; File: displayNum.asm ; ; Purpose: This is the displayNum.asm file which demonstrates how to obtain & display numbers to ; the screen in assembly using C functions. ; ;===== Begin code area ========================================================================================== extern printf ;External functions printf & scanf extern scanf ;taken from the C library which will be ;used for user input/output to the screen ; segment .data ;Place initialized data here ; ;======== Text declarations & variables which will be displayed to the user ===================================== getNumber db "Please enter a number: ",0 displayNumber db "The number you just entered is: ", 0 unsignedLongIntegerInput db "%lu", 0 stringDataOutput db "%s", 0 newLine db 10, 0 displayLineSeperator db "--------------------------------------------",10,0 ; ;;========= End of text declarations which will be displayed to the user ======================================== ; segment .bss ;Place un-initialized data here ; myInt resq 1 ;Pointer for use by scanf to store a number from the user ; segment .text ;Place instruction code here ; global DisplayNum ;DisplayNum- the declarationthat is visible ;for other programs to link to it ; DisplayNum: ;This is an entry point. Execution will begin here. ; ;============= Push registers to the stack ====================================================================== ;safe programming which pushes all registers to the stack so data doesnt get corrupted push rbp push rbx push rcx push rdx push rdi push rsi push rbp push r8 push r9 push r10 push r11 push r12 push r13 push r14 push r15 ; ;================ End of Push Registers ========================================================================= ; ; Left side: X86 instructions ;Right side: the narrative 'A.K.A'the story about this program. ; ;===== #1 Display Line Seperator ================================================================================ mov qword rdi, stringDataOutput ;Prepare printf for string output mov qword rsi, displayLineSeperator ;The 'line seperator' is displayed mov qword rax, 0 ;No vector registers used call printf ;printf is going to output the data ; ;===== #2 Prompt The User For Integer Input ===================================================================== mov qword rdi, stringDataOutput ;Prepare printf for string output mov qword rsi, getNumber ;A Prompt to enter in a number will be displayed mov qword rax, 0 ;No vector registers used call printf ;printf is going to output the data ; ;===== #3 This Obtains User Input Using Scanf =================================================================== mov qword rdi, unsignedLongIntegerInput ;Prepare scanf to get one 64-bit integer mov qword rsi, myInt ;Set up indirect addressing for scanf mov qword rax, 0 ;No vector registers used. call scanf ;The unsigned long integer is placed into 'myInt' ; ;===== #4 Prompt The User That An Integer Will Be Displayed ===================================================== mov qword rdi, stringDataOutput ;Prepare printf for string output mov qword rsi, displayNumber ;A Prompt to display the number will be displayed mov qword rax, 0 ;No vector registers used call printf ;printf is going to output the data ; ;===== #5 Display The Number To User ============================================================================ mov qword rdi, unsignedLongIntegerInput ;Prepare printf to output one 64-bit integer mov qword rsi, [myInt] ;'myInt' will be passed to printf mov qword rax, 0 ;No vector registers used. call printf ;printf is going to output the data ; ;===== #6 This Prints A Newline ================================================================================= mov qword rdi, stringDataOutput ;Prepare printf to make string output mov qword rsi, newLine ;The newline character ascii code is passed to printf mov qword rax, 0 ;No vector registers used. call printf ;printf is going to output the data ; ;===== #7 Display Line Seperator ================================================================================ mov qword rdi, stringDataOutput ;Prepare printf for string output mov qword rsi, displayLineSeperator ;The 'line seperator' is displayed mov qword rax, 0 ;No vector registers used call printf ;printf is going to output the data ; ; END CODE EXECUTION FOR DISPLAYNUM.ASM ; ;====== pop the registers back from the in reverse order stack ================================================== pop r15 pop r14 pop r13 pop r12 pop r11 pop r10 pop r9 pop r8 pop rbp pop rsi pop rdi pop rdx pop rcx pop rbx pop rbp ; ;===== END - RETURN TO CALLED FUNCTION ========================================================================== mov rax, 0 ;return 0 to the called function ret ;ret pops the stack taking away 8 bytes ; ; http://programmingnotes.org/ ; ;===== End of DisplayNum subprogram ============================================================================= |
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.
1 2 3 4 |
(1) Compile driver.c file: gcc -c -Wall -m64 -std=c99 -l driver.lis -o driver.o driver.c (2) displayNum.asm assembler file: nasm -f elf64 -l displayNum.lis -o displayNum.o displayNum.asm (3) Link all files: gcc -m64 -o displayNum.out driver.o displayNum.o (4) Execute in 64-bit protected mode: ./displayNum.out |
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.
Leave a Reply