Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Lab 1 ECE L 273 Overview of ECE L 273 http://www.parl.clemson.edu/ullab/ece272/ece272.html http://www.clemson.edu/ces/departments/ece/resources/ECE273Lab.html • Lab 1 – Introduction – Required tools • Lab2 – Assignment Statements – Basic Assembly Language Syntax • Lab3 – Control Statements – Loops, Branching • Lab4 – Addressing modes – Arrays and Pointers • Lab5 – Subroutines and Stack • Lab6 – Subroutine Parameters Structure • Lab assignment due after every 2 weeks. – 70% of the grade • In-Lab test during in-between weeks. – 15% of the grade • Final Exam – 15% of the grade Development Environment • Dual Boot – Install Linux on your laptop on a different hard disk partition • Virtualization Software – Run Linux using either VMware or VirtualBox on (Windows/MacOS) – http://www.clemson.edu/ces/departments/ece/r esources/virtualmachine.html • Remote Access – http://www.parl.clemson.edu/ullab/security.html Assembly Language • Programmer Perspective (Optimizing code) – Write most of the code in High Level Language like C or C++ for example. – Profile the code and identify which parts are executed most often and need to be optimized. – Rewrite that part of code in low level language (Assembly) to make it run faster. • Compilers – Compilers translate high-level language to lowlevel language. Example of use of Assembly Code #include <stdio.h> int main(int arg, char **argv) { char buffer[256]; do { int i = 0; printf ("Enter a string terminated with a newline\n"); do { buffer[i] = getchar(); } while (buffer[i++] != '\n'); buffer[i-1] = 0; /* asum() is the * function * implemented in * assembly */ i = asum(buffer); if (i) { printf ("ascii sum is %d\n", i); continue; } } while(1); return 0; } .global asum .type asum,@function asum: pushl %ebp movl %esp, %ebp subl $4, %esp movl $0, -4(%ebp) .L2: movl 8(%ebp),%eax cmpb $0,(%eax) jne .L4 jmp .L3 .L4: movl 8(%ebp),%eax movsbl (%eax),%edx addl %edx,-4(%ebp) incl 8(%ebp) jmp .L2 .L3: movl -4(%ebp),%eax jmp .L1 .L1: movl %ebp, %esp popl %ebp ret • Tools – Editors (vi, emacs, pico) – Compilers (gcc – GNU Compiler Collection) – Assembler (as – GNU Assembler) – Debugger (gdb – GNU Debugger) • Typical Steps – Write (C driver program, Assembly functions). – Compile & Assemble. – Link. – Execute. – Debug (if required). drv.c asm.s drv.c asm.s COMPILATION gcc -c -o drv.o drv.c as -o asm.o asm.s drv.o LINKING asm.o COMPILATION And LINKING gcc -o myprog drv.c asm.s gcc -o myprog asm.o drv.o myprog Run the program: .\myprog myprog Documentation http://www.parl.clemson.edu/ullab/documentation.html • Headers – Program Headers – Procedure Headers • Naming Convention – Variables and subroutine names • Comments – Uncommented code will not be accepted – Comments must relay purpose of the code and not just verbalize them. Program Header ////////////////////////////////////////////////////////////////////////////////////////////// // ECE 273 Lab // // NAME: Firstname Lastname // // SECTION: Four (12:20 - 2:20) M // // DATE DUE: Feb. 1, 1998 // // FILENAME: somefile.extension // // PROJECT: Lab Assignment #1 // // PURPOSE: This assembly program calculates the // // ASCII sum of the characters passed to // // it as a character array. // //////////////////////////////////////////////////////////////////////////////////////////// filename This should simply contain the name of the file in which this header is residing. project Should contain the name of the overall project. purpose Should briefly explain the what this program does. Program headers are included once per assignment at the top of the document. Procedure Header ////////////////////////////////////////////////////////////////////////////////////// // PROCEDURE: ProcedureName // // PARAMETERS: Listing of parameters // // RETURNS: Listing of data that gets returned // // DESCRIPTION: What this procedure does // ///////////////////////////////////////////////////////////////////////////////////// procedure Actual call name of the procedure. Use mixed case to emphasize procedure names like GetString instead of get_string. parameters Describe the registers or data passed into this procedure from the calling procedure. returns List any data being sent to the calling procedure upon termination of this procedure. description This should explain in detail the function of this procedure. Don't explain exactly how the procedure performs what you claim it can do, just explain what it does. How should be expressed in the procedure in comments. If a C program has only main, then there is no need for a procedure header. This is the only case when this is allowed simply because main is self explanatory. Naming Convention . constants Constants should be all capitalized, such as NULL, PI, or CR. procedure names Procedure names should use mixed case whenever possible, such as GetString, Sum, or ComputeAvg. local variables Local variables should be all lower case, such as sum, count, total, or value globals Globals should be proceeded by a _, such as _TRYTYPE, _BUFFER, or _STARTVALUE. Lab 2 ECE L 273 Goal • Write Assembly Language code to evaluate expressions like: int a,b,c,d,e; a = ((b + c) - (d + e)) - 10; • Learn about: – Variables – Registers – Assembly instructions. Assembly Language Programming • Program = Data + Control Instructions • Instructions can perform only one computation at a time. For example: – ADD : Add two numbers – MOV: Move data from one location to another – CMP: Compare two values • Data – Registers – Memory Functional Abstraction Registers Memory ALU Format of Instructions label: mnemonic operand1, operand2 /* comment*/ Example movl %eax, %ebx • Label – Is used to indicate address of instruction – It is optional. Not every instruction needs to have it. • Mnemonic – Specifies the instruction or command • Operand1, Operand2 – – – – Identify the data on which the instruction operates Not all instructions have both the operands. Operand1 is the Source and Operand2 is the Destination. Atleast one operand has to be a register. • Comment – Is used optionally to convey the meaning associated with the instruction Data - Registers These eight registers are available for storing operands and pointers. Data – Memory (variables) int a = 10; Assembler Directive Variable Name .comm a, movl $10, Constant Value Number of bytes 4 a a: Variable Name .int Data Type 10 Initialization Value Datatypes • Byte (8 bits) a: .char ‘s’ movb a, %bl addb $10, %bl • Word (16 bits) a: .short 10 movw, a, %bx subw $10, %bx • Long (32 bits) a: .int 100 movl a, %ebx mull %ebx Expression Evaluation • a = ((b + c) - (d + e)) - 10; – Evaluate ( b + c ) • Store result in Register (EAX) – Evaluate ( d + e) • Store result in another Register (EBX) – Evaluate ( b + c ) – (d + e ) • Subtract EBX from EAX • Store result by overwriting EAX – Evaluate ( b + c ) – (d + e ) – 10 • Subtract 10 from EAX • Store result by overwriting EAX – Store result back to variable a movl addl b, c, %eax %eax movl addl d, e, %ebx %ebx subl %ebx, %eax subl $10, %eax movl %eax, a Multiplication a: b: movl mull .int .int a, 10 20 16bit = 8bit * 8bit 32bit = 16bit * 16bit 64bit = 32bit * 32bit %eax b Implicitly specified Explicitly specified Implicitly specified Division (Quotient & Remainder) a: b: .int .int movl $0, movl a, divl 10 20 %edx %eax IMPORTANT b Output 1 Implicitly specified Implicitly specified Output 2 Implicitly specified Assignment int digit1, digit2, digit3; int diff; int sum; int product; int remainder; Implement using Assembly Programming dodiff() { diff = (digit1 * digit1) + (digit2 * digit2) - (digit3 * digit3); } dosumprod() { sum = digit1 + digit2 + digit3; product = digit1 * digit2 * digit3; } doremainder() { remainder = product % sum; } Template .globl dodiff .type dodiff, @function .globl dosumprod .type dosumprod, @function .globl doremainder .type doremainder, @function dodiff: dosumprod : doremainder : /* prolog */ pushl %ebp pushl %ebx movl %esp, %ebp /* prolog */ pushl %ebp pushl %ebx movl %esp, %ebp /* prolog */ pushl %ebp pushl %ebx movl %esp, %ebp /* put code here */ /* put code here */ /* put code here */ /* epilog */ movl %ebp, %esp popl %ebx popl %ebp ret /* epilog */ movl %ebp, %esp popl %ebx popl %ebp ret /* epilog */ movl %ebp, %esp popl %ebx popl %ebp ret Assignment – Due in 2 weeks Lab 3 ECE L 273 Goal • Write Assembly language instructions similar to following Control Statements: int a, b; if (a > b) { ... code block 1 ... } else { ... code block 2 ... } int i; for (i = 0; i < 100; i++) { ... code block 1 ... } int i; do { ... code block 1 ... } while(--i); Control Statements • Without control statements all the assembly instructions are executed sequentially (one after the other) • Non-trivial programs require – Conditional execution of code – Repetitive execution of same part code • Typical control structures available in High level languages are – If-else – For loop – switch Control Structures in Assembly • Control structures are not directly available in assembly language programming • Support for implementing the control structures is provided using – special register (EFLAGS), – side-effects, – conditional jumps (jle, jng, …) EFLAGS • EFLAGS is a 32-bit register with specific meaning assigned to bits within it. A bit within this register represents status of a flag. • Example Flags: – CF: Carry/Borrow – PF: Parity – ZF: Zero Flag – SF: Sign Flag Side Effects and EFLAGS • When an assembly instruction is executed, the result value determines what flags are set in EFLAGS register (side effects). – If the result is zero, ZF is set to 1 – If the result is negative, SF is set to 1 – And so on … • These changes are considered side effects as EFLAGS is not explicitly specified as operand for the assembly instructions. • Conditional jumps use side effects to determine which path within the program should be taken. Example if ( a > b ) { c = 10; } d = 20; Causes Side-Effect by setting flags like ZF or SF in EFLAGS Checks the EFLAGS and decides whether or not to jump to instruction at label lbl_skip. If the jump doesn’t take place then the immediately following instruction in executed movl a, %eax cmpl b, %eax jng lbl_skip movl $10, c lbl_skip: movl $20, d if-else construct Option 1 is preferred as it maintains the statement sequence as in it’s C equivalent. Also, it is easier to write nested if-else statements with option1. if ( a > b ) { s1 s2 }else { s3 s4 } s5 s6 Option 1 movl a, %eax cmpl b, %eax jng lbl_else s1 s2 jmp lbl_more lbl_else: s3 s4 lbl_more: s5 s6 Option 2 movl a, %eax cmpl b, %eax jg lbl_if s3 s4 jmp lbl_more lbl_if: s1 s2 lbl_more: s5 s6 if ( a > b ) { s1 s2 if (c > d) { s3 s4 } s5 s6 }else { s7 s8 } s9 s10 Nested if-else First, write code for the outermost if-else structure movl a, %eax cmpl b, %eax jng lbl_else . . . jmp lbl_more lbl_else: s7 s8 lbl_more: s9 s10 Next, fill in the code for the nested part. s1 s2 movl c, %eax cmpl, d, %eax jng lbl_nest s3 s4 lbl_nest: s5 s6 For loop Step1 Step2 Step4 Step1 for ( i = 0; i < 100; { s1 s2 Step3 } s3 s4 i++ ) movl $0, i lbl_for: cmpl $100, i jnl lbl_more s1 Step3 s2 inc i jmp lbl_for lbl_more: s3 s4 Step2 Step4 loop statement int i; do { s1 s2 } while( --i ); s3 s4 movl i, %ecx lbl_do: s1 s2 loop lbl_do lbl_more: s3 s4 Only %ecx can be used as counter register Every time loop instruction is executed, %ecx is auto-decremented by 1 (one). The loop breaks when %ecx reaches zero. Assignment – Due in 2 weeks Lab 4 ECE L 273 Goal • Write Assembly language instructions for handling Arrays and Pointers: int a[10]; int i = 2; main() { a[0] = 10; int a[10]; int *ap; int i = 3; main() { ap = &(a[0]); a[4] = 20; ap[3] = 50; a[i] = 30; ap[i] = 60; } } Pointers - Review • Pointer – A variable which contains memoryaddress of another variable. int x = 1, y = 2; int *ip; ip = &x; y = *ip; x 7 Addr=100 y 2 Addr=104 ip 100 Addr=108 x 7 Addr=100 y 7 Addr=104 ip 100 Addr=108 Address Arithmetic Address = 100 Address = 100 Address = 100 char a[10]; short a[10]; int a[10]; char *pa = &a; short *pa = &a; int *pa = &a; pa = pa + 1; pa = pa + 1; pa = pa + 1; Address increments by 1. pa = 101 Address increments by 2. pa = 102 Address increments by 4. pa = 104 Addressing Modes • Immediate • Indexed • Register • Register Indirect • Direct • Base-Indexed Immediate and Register Immediate Addressing Mode Register Addressing Mode • movl $4, %eax • movl %eax, %ebx Data value itself is known at compile time Location (Register) of Data value is known at compile time Direct Addressing Mode C Code Equivalent Assembly Code int a[10]; .comm a 40 Address of a is same as address of a[0] int i = 2; i: .int 2 a[0] = 10; movl $10, a a[4] = 20; movl $20, a + 16 Address of a and Address a + 16 are known at compile time. Indexed Addressing Mode “ i ” is a variable and it’s value need not be known at compile time. Address of a[i] is not known during compilation; it has to be calculated at runtime. C Code Equivalent Assembly Code int a[10]; .comm a 40 int i = 2; i: .int 2 a[i] = 30; movl i, %edi movl $30, a(, %edi, 4) Two step process: 1. Use %edi as index register 2. Identify address of data as: a + (%edi * 4) Base Address Offset in bytes Register Indirect Addressing • The address of data is specified in the register %ebx int *p; main() { *p = 40; } .comm p, 4 int arr[10]; movl arr, %ebx arr[2] = 20; movl $20, 8(%ebx) movl p, %ebx movl $40, (%ebx) Identify address of data as: %ebx + 8 Base Indexed Addressing • Address = BaseAddress + Index*sizeofdata • BaseAddress is specified by %ebx • Index is specified by either %esi or %edi int *ap; int i; .comm ap, 4 .comm i, 4 main() { ap[i] = 60; } movl ap, %ebx movl i, %edi movl $60, (%ebx, %edi, 4) Two step process: 1. Use %edi as index register 2. Identify address of data as: %ebx + (%edi * 4) Recap • Immediate – movl $4, %eax • Register – movl %eax, %ebx • Direct – movl %eax, a – movl %eax, a+16 • Indexed – movl $30, a(, %edi, 4) • Register Indirect – movl $40, (%ebx) • Base-Indexed – movl $60, (%ebx, %edi, 4) Assignment – Due in 2 weeks ECE L 273 Lab 5 Goal • Write Subroutines in Assembly Language • Handle Local Variables subadd () { int a; a = 10; a = a + 20; } subadd: pushl %ebp movl %esp, %ebp subl $4, %esp movl addl $10, $20, movl popl %ebp, %esp %ebp ret -4(%ebp) -4(%ebp) Functions And Subroutines • Help write modular programs • Pascal, Fortran, Ada – Function -> returns a value – Subroutine -> does not return any value • C – No distinction made between function and subroutines • Assembly subroutine call example – call subadd Call Vs Jmp • Any program label can be a subroutine • Any label you can “jmp” to can be “call”ed as subroutine • Difference – When you “call” a subroutine, the “return addr” is saved on a Stack – After “ret” is executed, the program returns to the instruction immediately after the “call” Stack – Push and Pop operation PUSH POP Return Address 96 100 104 108 200 204 208 . . . 220 call subadd mov %eax, %ebx Push return address (104) onto the stack and jump to subroutine subadd at address 200. subadd: ret Pop return address from stack and start executing from address 104. Local Variables • Allocated on the stack – Stack Frame • Recursion – Each instance of the recursion creates its own stack frame • Stack Frame – Base => %ebp – Top => %ebp + Total Bytes for Local Variables Stack Frame – Local Variables subadd () { int a; a = 10; a = a + 20; } 4 bytes for local variable “a” Stack Frame %esp a %ebp old Save calling function’s Stack Frame base subadd: pushl %ebp movl subl %esp, %ebp $4, %esp Establish base of current Stack Frame Allocate memory for local variables. Stack Frame is created. movl addl $10, $20, -4(%ebp) -4(%ebp) movl %ebp, %esp popl %ebp %ebp ret Deconstruct “Stack Frame”. De-allocate local variables. Restore calling function’s Stack Frame base Nested Calls - Stack Growth Return Address of “doubleit” Return Address of “main” main doubleit halfit Assignment – Due in 2 weeks ECE L 273 Lab 6 Goal • Pass Parameters to Subroutines subRtn() { int a, b; a = 10; b = doubleit(a); } doubleit(int num) { return 2*num; } doubleit: pushl %ebp movl %esp, %ebp #Access parameter num movl 8(%ebp), %eax mull $2 movl popl ret %ebp, %esp %ebp Parameter Passing • Registers – Arguments passed using agreed-upon registers – Restricted due to number of available registers • Stack – Any number and any size arguments – Caller pushes parameters onto stack before calling subroutine – Callee uses offset from %ebp to access parameters Using Registers foo: pushl %ebp movl %esp, %ebp movl a, %eax #Use %eax to pass parameter call bar movl %ebp, %esp popl %ebp ret extern int a, b; foo() { bar(a); } bar(int p1) { b = b + p1; } bar: pushl %ebp movl %esp, %ebp #Use %eax for a addl %eax, b movl %ebp, %esp popl %ebp ret Using Stack extern int a, b, c, d, e; foo() { // Parameters are // pushed in reverse // order e = bar(a, b, c, d); } bar() int p1, p2, p3, p4; { return (p1+p2)*(p3+p4); } foo: pushl %ebp movl %esp, %ebp #Push parameters on #stack pushl d pushl c pushl b pushl a call bar #Remove parameters #from stack addl 16, %esp #extract return value movl %eax, e movl popl ret %ebp, %esp %ebp bar: pushl movl pushl %ebp %esp, %ebp %ebx movl addl movl addl mull 8(%ebp), %eax 12(%ebp), %eax 16(%ebp), %ebx 20(%ebp), %ebx %ebx popl movl popl ret %ebx %ebp, %esp %ebp Stack – With Parameters bar: pushl movl pushl %ebp %esp, %ebp %ebx (%esp) (%ebp) %ebx old %ebp movl addl movl addl mull 8(%ebp), %eax 12(%ebp), %eax 16(%ebp), %ebx 20(%ebp), %ebx %ebx 8(%ebp) 12(%ebp) 16(%ebp) 20(%ebp) popl movl popl ret %ebx %ebp, %esp %ebp retAddr_foo a b c d older %ebp Ret Address Return Value • Usually using register %eax • Some languages like C and Modula allow complex types to be returned. • Return value is pushed onto the stack and a pointer is returned in an agreed-upon register. Assignment – Due in 2 weeks