End of Course Experience


======Part 1: Questions====== ====System Calls==== ===0x0:=== A system call is the means by which an assembly program interacts directly with the operating system's kernel. For example, the system call for exiting a program: mov eax, 1 ;Putting 1 into eax represents exit program mov ebx, 0 ;Putting 0 in to ebx means return 0 int 0x80 ;Activate Interrupt 80h (the system kernel on linux) ====Registers==== ===0x1:=== A register is a memory space directly on the CPU. Variables in higher languages exist off CPU in the system memory. ===0x2:=== The general use registers on the x86 CPU are EAX, EBX, ECX, EDX and they each hold 32 bits of binary data. ===0x3:=== Registers store everything in binary (0s & 1s), and therefore have no data type. The only difference is the number of bits that each register can hold -- some are 32 bits, some are 16 bits, and some are 8 bits. ====Stacks==== ===0x4:=== The stack is a Last-In, First-Out (LIFO) memory space that is often utilized for saving the current state of a register for later retrieval. For example, to save and restore the state of the ecx register: mov ecx, 1 ;Puts 1 into ecx push ecx ;Adds 1 onto the stack for ecx mov ecx, 2 ;2 is now stored in ecx pop ecx ;1 is removed from the stack and placed back into ecx ====Branching==== ===0x5:=== Branches, or jumps (jmp) are typically used for goto functionality, for looping operations, and for conditional based logic decisions (if-then-else). Loops and conditional jumps are preceded by a comparison (cmp) instruction, which sets zero flag (ZF) and carry flag (CF) accordingly. The cmp instruction also can also set other flags, but these two are used the most frequently when beginning to learn x86 ASM. For straight jumps: jmp myJump ;Would jump to the label myJump For conditional jumps: cmp eax, ebx ;If both ZF and CF are unset, then eax is greater than ebx. ;If ZF is set, and CF is unset, then eax is equal to ebx. ;If ZF is unset and CF is set, then eax is less than ebx. Followed by: ja myJump ;Would jump to the label myJump if eax is greater than ebx jae myJump ;Would jump if eax is greater than or equal to ebx je myJump ;Would jump if eax is equal to ebx jne myJump ;Would jump if eax is not equal to ebx jb myJump ;Would jump if eax less is than ebx jbe myJump ;Would jump if eax is less than or equal to ebx There are more jump commands than these, but they are the main ones used for loops and if-then-else. ====Labels==== ===0x6:=== Labels are used as a symbolic means of identifying a particular portion of code to be referred to by other parts of the program. They are most commonly used in conjunction with jmp and call instructions. Jumps go to the location of label and begin executing instructions in sequence without returning. A call on the other hand will return back to the sequence from which the call instruction originated when the code sequence after a label uses a ret (return) instruction. ===0x7:=== It is necessary have a specific means to symbolically identify the start of a program, otherwise the computer does not know where to begin. Typically, most high level languages begin program execution with a function called "main". Assembly, depending on the compiler you use will typically use the labels "_start" or "_asm_main" to identify the start of the program. ======Part 2: Programs====== ====EoCE Macro File====

All programs written for the EoCE make use of a macro file named 0x0.mac

; Raymond Young ; 0x0.mac %ifndef MY_INCLUDES %define MY_INCLUDES %define sysExit 0x1 %define sysWrite 0x4 %define sysRead 0x3 %define sysScreen 0x1 %define sysConsole 0x1 %define sysKernel 0x80 %endif segment .data asciiNewline db 0xA, 0x0 segment .bss ; Data Management Macros %macro macCopyTo 2 ; Copies %1 to %2 mov ecx, %1 mov ebx, %2 mov edx, [ecx] mov [ebx], edx %endmacro; macCopyTo ; Character Manipulation Macros %macro macAtoI 1 ; Converts the ASCII character in %1 to an integer ; Example: '0' (0x30) -> 'null' (0x0) mov ecx, %1 mov edx, [ecx] and edx, 0xF mov [ecx], edx %endmacro; macAtoI %macro macItoA 1 ; Converts the integer in %1 to an ASCII character ; Example: 'null' (0x0) -> '0' (0x30) mov ecx, %1 mov edx, [ecx] or edx, 0x30 mov [ecx], edx %endmacro; macItoA ; String Manipulation Macros %macro macInsrtNl 1 ; Inserts the newline character at the current ; location of ecx mov edx, 0xA mov [%1], edx %endmacro; macInsertNl %macro macInsrtNul 1 ; Inserts the null character at the current ; location of ecx mov edx, 0x0 mov [%1], edx %endmacro; macInsertNul %macro macApndEOS 1 ; Appends "end of string" (Newline & Null characters ; at the current location of %1 ; requires ecx to point to the end of the string macInsrtNl %1 inc %1 macInsrtNul %1 %endmacro; macApndEOS ; Input / Output System Calls %macro macPrint 2 mov eax, sysWrite mov ebx, sysScreen mov ecx, %1 mov edx, %2 macKernel %endmacro; macPrint %macro macRead 2 mov eax, sysRead mov ebx, sysConsole mov ecx, %1 mov edx, %2 macKernel %endmacro; macRead %macro macNewline 0 macPrint asciiNewline, 1 %endmacro; macNewline %macro macCleanExit 0 mov eax, sysExit xor ebx, ebx macKernel %endmacro; macCleanExit %macro macKernel 0 int sysKernel %endmacro; macKernel ====Adding without Addtion==== ===0x8:===

Performing bit-wise arithmetic

; Raymond Young ; 0x8.asm %include '0x0.mac' segment .bss sum resb 0xF carry resb 0xF segment .data msg1 db 'Enter a number: ', 0x0 msg2 db 'Enter another: ', 0x0 segment .text global _start _start: nop ; create a clean working environment enter 0, 0 pusha ; get the first number macPrint msg1, 17 macRead sum, 0xF ; get the second number macPrint msg2, 16 macRead carry, 0xF ; convert the ascii values to integer values macAtoI sum macAtoI carry ; add them using bit-wise arithmetic _addloop: ; find the sum using xor ; place the first number in ecx mov ecx, [sum] ; place the second number in edx mov edx, [carry] ; save edx to the stack push edx ; xor ecx against edx and store the result in edx xor edx, ecx ; save the result to the sum mov [sum], edx ; find the carry using and ; retriev the second number from the edx stack pop edx ; and ecx against edx and store the result in edx and edx, ecx ; bit shift the result to the left by 1 bit shl edx, 0x1 ; save the result to the carry mov [carry], edx ; check to see if the carry is equal to 0 cmp edx, 0x0 ; if the carry is not 0 we need to repeat xor & and jne _addloop ; convert the integer value to an ascii value macItoA sum ; append the end of string identifier mov ecx, sum inc ecx macApndEOS ecx ; display the results macPrint sum, 0xF ; exit cleanly macCleanExit popa leave hlt ====Swapping Values==== ===0x9:===

Swapping values using registers

; Raymond Young ; 0x9.asm %include "0x0.mac" segment .bss abc resb 0xFF def resb 0xFF segment .data msg1 db 'Enter 1st character: ', 0x0 msg2 db 'Enter 2nd character: ', 0x0 segment .text global _start _start: nop ; create a clean working environment enter 0, 0 pusha ; get the first character macPrint msg1, 21 macRead abc, 0xFF ; get the second character macPrint msg2, 21 macRead def, 0xFF ; perform the character swap ; place the first character in eax mov eax, [abc] ; place the second character in ebx mov ebx, [def] ; swap them xchg eax, ebx ; store the swapped characters mov [abc], eax mov [def], ebx ; display the results macPrint abc, 0xFF macPrint def, 0xFF ; exit cleanly macCleanExit popa leave hlt ====Reversing Strings==== ===0xA:===

Reversing a string

; Raymond Young ; 0xA.asm %include "0x0.mac" segment .bss abc resb 0xFF def resb 0xFF segment .data msg1 db 'Enter a string: ', 0x0 segment .text global _start _start: nop ; create a clean working environment enter 0, 0 pusha ; get our input string macPrint msg1, 17 macRead abc, 0xFF ; prepare the edx stack ; put a leading newline onto the stack mov edx, 0xA ; place the pointer to our input string in ecx mov ecx, abc ; place the pointer to our output string in ebx mov ebx, def ; store the characters in the edx stack while looking ; for the end of the string in ecx _ecxLoop: ; put the current letter onto the top of the edx stack push edx ; read the next letter from the string ecx points to mov edx, [ecx] ; drop all but the current letter from edx and edx, 0xFF ; increment the ecx pointer for the next read inc ecx ; compare the current letter against the newline character cmp edx, 0xA ; if not newline, repeat, else drop through jne _ecxLoop ; rebuild the string in reverse order using the edx stack ; using the leading newline to mark the end of the string ; pull the first letter from the top of the edx stack pop edx _ebxLoop: ; place the letter into the position of the string ; that ebx currently points to mov [ebx], edx ; increment the ebx pointer for the next write inc ebx ; pull the next letter from the top of the edx pop edx ; compare the new letter against the newline character cmp edx, 0xA ; if not newline, repeat, else drop through jne _ebxLoop ; append the end of string identifier macApndEOS ebx ; display the reverse of the input string macPrint def, 0xFF ; exit cleanly macCleanExit popa leave hlt ====Uppercasing a String==== ===0xB:===

Capitalize lower case letters

; Raymond Young ; 0xB.asm %include "0x0.mac" segment .bss abc resb 0xFF def resb 0xFF segment .data msg1 db 'Enter a string: ', 0x0 segment .text global _start _start: nop ; create a clean working environment enter 0, 0 pusha ; get the input string macPrint msg1, 17 macRead abc, 0xFF ; primer to perform the to upper conversion ; place the pointer to our input string in ecx mov ecx, abc ; place the pointer to our output string in ebx mov ebx, def ; read the next letter from the string ecx points to mov edx, [ecx] ; drop all but the current letter from edx and edx, 0xFF ; loop through the string till newline is found _ecxLoop: ; determine of the current letter is between a and z ; determine if the current letter comes before 'a' cmp edx, 0x61 ; lowercase a in hex ; jump if before 'a', else drop through jb _storeLetter ; determine if the current letter comes after 'z' cmp edx, 0x7A ; lowercase z in hex ; jump if after 'z', else it's a charater to uppercase ja _storeLetter ; subtract 32 from the value of the current character and edx, 0xDF ; update the input string _storeLetter; ; place the letter into the output string that ebx points to mov [ebx], edx ; increment the ebx pointer for the next write inc ebx ; increment the ecx pointer for the next read inc ecx ; read the next letter from the string ecx points to mov edx, [ecx] ; drop all but the current letter from edx and edx, 0xFF ; compare the new letter against the newline character cmp edx, 0xA ; if not newline, repeat, else drop through jne _ecxLoop macApndEOS ebx ; display the results macPrint def, 0xFF ; exit cleanly macCleanExit popa leave hlt ======Part 3: Wrapping Up====== ====FAQs==== ===0xC:=== {{page>user:ryoung12:eoce:asm:macros}} ====The Philosophical Impact of ASM==== ===0xD:=== Q: Why is it important that a computing curriculum include assembly language? A: ASM is the root of all other computer languages, as most of the "higher-level" languages are built upon ASM. \\ Q: What benefit does it possess for your understanding and programming ability? A: By knowing the general workings of ASM allows a programmer to have more thorough understanding of what is going on in the background when writing software using the methods and routines of a higher level language. \\ Q: How has it changed your perspective with regard to writing programs and algorithms? A: From being able to visualize the steps that would need to be done in ASM to perform the instructions as written in a higher level language, it is possible to write code that is far more efficient in its use of the CPU, by knowing how to reduce the number of logical operations that are performed by the program. ====The Assembly Language Paradox==== ===0xE:=== Q: How is assembly language both simpler yet more work than a higher level language? A: ASM is a lot simpler than a higher level language because there are far fewer keyword based control structures. Yet it is more work because ASM a direct one-to-one relationship between lines of instruction and number of operations performed by the CPU. Where as one command in a higher level language could require the CPU to perform many different operations before the command has been completed. \\ Q: Why is the devil in the details? A: To properly program in ASM, one needs to fully understand how to use the registers, flags, and OS-dependent system calls, in addition to being aware of Endianness, stack pointers, etc. ====Student Perspective==== ===0xF:=== Q: What grade do you feel you deserve for this course? A: 0x41 (ASCII letter A in hex) \\ Q: Why do you feel you deserve this mark? A: I kept up my journals. I completed the homework assignments on time. And I learned the material well enough to go above and beyond the immediate scope of the course. \\ Q: How did you feel about the course? A: In the beginning of the semester, I felt overwhelmed and intimidated by ASM; for at least the first month. But as time passed, and I began to understand things better, I felt more comfortable programming in assembly. I won't go so far as to say I am now an expert in assembly, but I feel comfortable enough with the language now that I could write a program or two in it as the need arises. \\ Q: Was it useful/interesting to you? A: I've always been interested in learning assembly because of the many uses it has in the computer world, so yes. \\ Q: What was your least favorite aspect, and why? A: Well, I felt that during the middle of the semester, the course could have used a bit more guidance and direction in terms of instructional lessons and homework assignments consisting of programming exercises based on the current lesson. \\ Q: What was something meaningful to you with respect to the course? Why does this stick out in your mind? A: I can honestly say I know how to program in assembly language now. -- This sticks out in my mind because I was of the belief that I would never learn ASM prior to taking this course. \\ Q: Any other comments or suggestions? A: For a course that focuses on learning a new programming language, and especially one (like assembly) that differs greatly from the commonalities of the major programming languages (c/c++, java, etc) and their derivatives, a more directed lesson for each lecture period would be of tremendous help. ~~NOCACHE~~