Chapter 8 - Variables, printf, scanf
8.1 Data Definitions
Memory can be reserved to store data or variables in
the .data and .bss sections. In the .data section, values are defined.
In the .bss section, memory is reserved but not initialized until runtime where
is set to 0. This can make the executable smaller by not having to store
the values of 0 for each variable. Below are some examples.
;====================================== section '.data' data readable writeable ;====================================== NewLine db 10 ;declare a byte value 10 A db 5,10,15 ;declare 3 bytes with values 5,10,15 Alpha db 'abc' ;declare 3 bytes with values 97,98,99 B dd 0xFFFF ;declare 4 bytes with value 65535 Pi dq 3.14159 ;declare 8 bytes with a float C dd ? ;declare 4 bytes uninitialized ;===================================== section '.bss' data readable writeable ;===================================== Age1 rb 1 ;reserve 1 byte Answer rb 16 ;reserve 16 one byte cells Stats rq 1 ;reserve an 8 byte cell Ages rd 5 ;reserve 5 cells of 4 bytes each |
Notes: 1. Each character byte is stored as its ASCII value. 2. Negative numbers are converted to 2's complement. 3. Floating point numbers are stored in either 32 bits (single precision) or 64 bits (double precision). |
8.2 printf
The printf function is contained in the C library
stdio.h. To use it in your code, the Microsoft C standard library
msvcrt.dll and the printf function must be imported. The printf function
takes a string to be printed to standard out. It can contain the format
specifiers shown below, each preceded with a percent sign %. The format
specifier may be preceded with flags, width, and precision values.
|
|
Below is an example assembly program and equivalent c++ program demonstrating printf. Since printf expects a double (8 bytes) for floating points, you have send it the first 32 bits (dword) and then the second 32 bits. This uses the size directive dword to specify 32 bits.
|
|
The printf function expects a 4 byte operand for printing an integer or decimal (%d). The program below shows how to print a single byte (db) variable and 2 byte (dw) variable. They must be loaded into a 4 byte register before sending to printf. Why doesn't this work if A or B is negative?
|
The printf command overwrites registers eax, ecx, and edx, therefore you need to store values you need to print and save value in registers to variables (memory). This why the above program uses the ebx register.
8.3 scanf
The scanf function is used to get user keyboard input
and is contained in the C library stdio.h. To use it in your code, the Microsoft C standard library
msvcrt.dll and the scanf function must be imported. Below are examples for
inputting a string, decimal, and float.
scanf2.asm |
format PE console include 'win32ax.inc' ;======================================= section '.code' code readable executable ;======================================= start: cinvoke printf, "Enter your first name: " cinvoke scanf, "%s", Fname cinvoke printf, "Enter your IQ: " cinvoke scanf, "%d", IQ cinvoke printf, "Enter a value for Pi: " cinvoke scanf, "%lf", Pi ;The middle character of %lf is a lowercase "L" cinvoke printf, "Hello %1.20s, IQ=%d Pi=%1.2f %c", Fname, [IQ], dword [Pi], dword [Pi+4], 10 invoke Sleep,-1 ;====================================== section '.bss' data readable writeable ;====================================== Fname rb 20 IQ rd 1 Pi rq 1 ;==================================== section '.idata' import data readable ;==================================== library msvcrt,'msvcrt.dll',kernel32,'kernel32.dll' import msvcrt,printf,'printf',scanf,'scanf' import kernel32,Sleep,'Sleep' |
Output |
Enter your first name:
David Enter your IQ: 120 Enter a value for Pi: 3.1415 Hello David, IQ=120 Pi=3.14 |