UMBC | CMSC 313 -- Sequential Instructions | Previous | Next |
Since we are going to cover the entire gauntlet of instructions, we will focus on only part of the General-Purpose. We also are going to focus on structured programming.
Since you are already familiar with that, we can relate to it. This includes most of the C/C++ operators. Since we can only do one "operator" at a time, the operator precedence does not apply. So let's look at them:
;; [ The .data section ] ;; This section is for defining constants, such as filenames or buffer sizes, ;; It includes the initialized variables section .data mystring db 'i is %d',10,0 ;; [ The .bss section ] ;; This section is where you declare your uninitialized variables. ;; They look something like this: ;; ;; filename: resb 255 ; REServe 255 Bytes ;; number: resb 1 ; REServe 1 Byte section .bss i: resd 1 ;; [ The .text section ] The actual code section .text ;; Declarations for gcc so we can use the standard C libraries extern printf global main ;must be declared for linker (ld) ;; just like main in C -- if linking with gcc, must be main, otherwise does not have to. main: ;tell linker entry point ;; put your code here ; give i a value mov dword [i], 12 ;Do a printf! push dword [i] ; one of my integer variables push dword mystring ; pointer into my data segment call printf add esp, 8 ; clean up the mess ;; The final part of the program must be a call to the operating system to exit ;;; the program. mov ebx,0 ;successful termination of program mov eax,1 ;system call number (sys_exit) int 0x80 ;call kernel ;; Notice the file just ends.The output is:
[~/courses/umbc/CMSC313/spring04/lectures/Lect04]$ sequential i is 12 [~/courses/umbc/CMSC313/spring04/lectures/Lect04]$
#includeint main( void ) { int i; i = 12; printf("i is %d\n", i ); return 0; }
Now to explain what went on!
We need to have an initialized variable that will hold the print specification needed by the the printf:
section .data mystring db 'i is %d',10,0
There is a declaration of an uninitialized variable named i. When using gcc, an int is four bytes long, so we must declare it as a double word to get a four-byte variable.
section .bss i: resd 1
The #include declares the prototype of the functions in stdio.h. We must explicitly declare those as extern, because their definition is external to this file. This is the same as in C/C++.
;; Declarations for gcc so we can use the standard C libraries extern printf
We have to give the variable a value. Notice there is a major distinction between the contents of the variable and the address of the variable! When we refer to the contains, we must put the brackets around the name of the variable! Without them, we are referring to the address of the variable!
When C/C++ invoke a function, the arguments to the function must be put on the stack. In the statement:
push dword [i] ; one of my integer variables push dword mystring ; pointer into my data segment
NOW! Let's invoke (or call) the function:
call printf
Notice that two double words were put on the stack. The programmer must take off everything that was put on the stack! There are a couple of ways to do this. One is to pop the contents into a register:
pop eax pop eaxOf course that does not work if we have something in eax that we do not want to lose! Another was is simply adjust the stack pointer so that we no longer point to what is no longer valid.
add esp, 8 ; 2 doublewords X 4 bytes per double ; wordBoy, that was hard...;-)
label: mnemonic dest, src
mov dword [i], 3 ; since we are placing i, we can use it temporarily. add dword [i], 4
mov eax, [a] add eax, 2 mov dword [i], eax
mov eax, [a] add eax, [b] mov dword [i], eax
inc dword [i]
dec dword [i]
;; [ The .data section ] ;; This section is for defining constants, such as filenames or buffer sizes, ;; It includes the initialized variables section .data mystring db 'i is %d',10,0 a dd 50 b dd 100 ;; [ The .bss section ] ;; This section is where you declare your uninitialized variables. ;; They look something like this: ;; ;; filename: resb 255 ; REServe 255 Bytes ;; number: resb 1 ; REServe 1 Byte section .bss i: resd 1 ;; [ The .text section ] The actual code section .text ;; Declarations for gcc so we can use the standard C libraries extern puts extern printf extern scanf global main ;must be declared for linker (ld) ;; just like main in C -- if linking with gcc, must be main, otherwise does not have to. main: ;tell linker entry point ;; put your code here ; ; Assignment ; ;i = 12; mov dword [i], 12 push dword [i] ; one of my integer variables push dword mystring ; pointer into my data segment call printf add esp, 8 ; ; Addition ; ;i = 3 + 4; mov dword [i], 3 ; since we are placing i, we can use it temporarily. add dword [i], 4 push dword [i] ; one of my integer variables push dword mystring ; pointer into my data segment call printf add esp, 8 ;i = a + 2; mov eax, [a] add eax, [b] mov dword [i], eax push dword [i] ; one of my integer variables push dword mystring ; pointer into my data segment call printf add esp, 8 ;i = a + b; mov eax, [a] add eax, [b] mov dword [i], eax push dword [i] push dword mystring call printf add esp, 8 ; i++; inc dword [i] push dword [i] push dword mystring ; pointer into my data segment call printf add esp, 8 ; i--; dec dword [i] push dword [i] push dword mystring ; pointer into my data segment call printf add esp, 8 ;; The final part of the program must be a call to the operating system to exit ;;; the program. mov ebx,0 ;successful termination of program mov eax,1 ;system call number (sys_exit) int 0x80 ;call kernel ;; Notice the file just ends.
If we add nine and nine, we get.......trouble. It does not fit. But if we simply ignore the carry, then the answer is 8 and it fits.....Not a perfect solution. Well, all we need is a place to store the carry and it is OK. That is where the carry flag comes into play! In our case of 9 + 9, we get 8 with the carry going into the carry flag (CF). Think about how we did math in the third grade, one column at a time, with a carry.
Sometimes, we need to know if the answer is positive or negative! Every math operation copies the most significant bit into the Sign Flag (SF). Then all we have to do is check the SF to get that information. Nice and easy.
What if the number is zero? This is a special condition that can do a lot for us. Every math operation sets the Zero Flag (ZF) according to the results of the operation. If the answer is zero, the ZF is set, otherwise it is cleared. One way that we use it is to check for equality. If src - dest is zero, they are equal! We now have a test for equality! We will return to this later.