程序代写代做代考 assembly assembler mp2 Warmup Directions

mp2 Warmup Directions

mp2 Warmup Directions (Updated 1/25/2016 by Ron Cheung for tutor VMs)

Study the lecture notes on the tools and instruction set. Then follow along

with this document. Make sure everything works for you as it is shown here and

that you understand *everything*. Turn in your work on this “warmup” along with

the rest of your MP2 assignment.

Here’s your first snippet of assembler. It is written in i386-as using 32 bit

quantities as follows:

movl $8, %eax

addl $3, %eax

movl %eax, 0x200

Let’s see how to get this to run on a SAPC. Since it only uses registers and a

memory location, it doesn’t need any “startup” module. We just have to get

these instructions into memory and execute them.

1. Put the gas assembler source code in a file called tiny.s

tiny.s:

movl $8, %eax

addl $3, %eax

movl %eax, 0x200

int $3

.end

I’ve added the “int $3” to trap back to Tutor at the end. Note also that I

have used the pseudo-op .end to tell the assembler that this is the end of the

code to be assembled.

2. Build an executable by running the assembler i386-as and then the loader

i386-ld. Normally we would put these commands in a makefile, but here you want

to become familiar with the individual steps.

—————

ulab(1)% i386-as –al -o tiny.opc tiny.s

1 tiny.s:

2

3 0000 B8080000 movl $8, %eax

3 00

4 0005 83C003 addl $3, %eax

5 0008 A3000200 movl %eax, 0x200

5 00

6 000d CC int $3

7 000e 9090 .end

ulab(2)% i386-ld -N -Ttext 0x1000e0 -o tiny.lnx tiny.opc

—————

Here the -N flag tells ld to make a self-sufficient, simple executable, and

the “-Ttext 0x1000e0” tells it to start the code area at 1000e0, so that the

code itself will start 0x20 bytes after that, at 100100. (There’s a 0x20-byte

header at the start)

3. We can look at the contents of tiny.lnx with the help of i386-objdump,

which is available under the simpler name “disas” for disassembly. To get the

hex contents as well as the disassembly, use “–full”:

—————

ulab(3)% disas –full tiny.lnx (on UNIX, can look at .lnx)

tiny.lnx: file format a.out-i386-linux

Contents of section .text:

0000 b8080000 0083c003 a3000200 00cc9090 …………….

Contents of section .data:

Disassembly of section .text:

00000000 movl $0x8,%eax

00000005 addl $0x3,%eax

00000008 movl %eax,0x200

0000000d int3

0000000e nop

0000000f Address 0x10 is out of bounds.

—————

This shows that the machine code in hex is

b8080000 0083c003 a3000200 00cc9090

at offset 0000 in the .text area. (.text just means code.) Actually the last

9090 is off the end of the designated code. With the help of the offsets for

each instruction, we can divide up the hex contents by instruction:

b808000000 movl $0x8, %eax at offset 0

83c003 addl $0x3,%eax at offset 5, so movl is 5 bytes of code

a300020000 movl %eax, 0x200 at offset 8, so addl is 3 bytes

cc int $3 at offset d, so movl is 5 bytes

90 nop at offset e, so int is 1 byte

90 at offset f, so nop is 1 byte

Later, we will cover how to encode instructions in bits, but for now it is

interesting to find the 0x200 address hidden in the movl %eax, 0x200

instruction, and the 08 and 03 in the first two. Surprisingly, the 08 takes

up 4 bytes but the 03 only one. The instruction set is optimized to be able

to add small numbers into registers very quickly. The instruction size is

important to speed because each instruction must be read out of memory before

it can be executed.

4. We download and run tiny.lnx on the tutor VM, executing one instruction at a

time to see how the registers change. To execute one instruction at a time,use

the “t” command in Tutor, for “trace”. To get started, set the EIP to 100100,

pointing the CPU to address 100100 as the next instruction to execute.

—————

Logon to tutor-vserver VM using credentials provided.Transfer the tiny.lnx file

from ulab to the VM using:

tutor-vserver$ scp username@users.cs.umb.edu:cs341/mp2/tiny.* .

tutor-vserver$ ls

you should see all the tiny.* files. Download the tiny.lnx file from tutor-

vserver VM to the tutor VM:

tutor-vserver$ mtip -f tiny.lnx

For command help, type ~?

For help on args, rerun without args

Code starts at 0x100100

Using board # 1

(hit here)

Tutor> ~downloading tiny.lnx //enter ~d

.Done.

Download done, setting eip to 100100

Tutor> md 100100 //Look at the code: same as above

00100100 b8 08 00 00 00 83 c0 03 a3 00 02 00 00 cc 90 90 …………….

Tutor> rd

EAX=0000000b EBX=00009e00 EBP=000578ac

EDX=00101b88 ECX=00101bac ESP=003ffff0

ESI=00090800 EDI=00101d5c EIP=0010010d

EFLAGS=0302 (IF=1 SF=0 ZF=0 CF=0 OF=0)

Tutor> md 200 //Check target area using md or mdd

00000200 0b 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….

Tutor> ms 200 00000000 //Clear target area(8 0’s for 32-bit write)

Tutor> md 200 //Check again–OK

00000200 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….

Tutor> rs eip 100100 //Set initial EIP to start addr

Tutor> t //Trace: execute 1 instruction

Exception 1 at EIP=00100105: Debugger interrupt

Tutor> rd //See EIP at 100105 (i.e. offset 5), and

EAX=00000008 EBX=00009e00 EBP=000578ac //8 now in EAX

EDX=00101b88 ECX=00101bac ESP=003ffff0

ESI=00090800 EDI=00101d5c EIP=00100105

EFLAGS=0302 (IF=1 SF=0 ZF=0 CF=0 OF=0)

Tutor> md 200 //Check target area: nothing yet

00000200 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….

Tutor> t //Execute 2nd instruction

Exception 1 at EIP=00100108: Debugger interrupt

Tutor> rd //See b in eax, eip to offset 8

EAX=0000000b EBX=00009e00 EBP=000578ac

EDX=00101b88 ECX=00101bac ESP=003ffff0

ESI=00090800 EDI=00101d5c EIP=00100108

EFLAGS=0302 (IF=1 SF=0 ZF=0 CF=0 OF=0)

Tutor> md 200 //Check target area: nothing yet

00000200 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….

Tutor> t //Execute 3rd instruction

Exception 1 at EIP=0010010d: Debugger interrupt

Tutor> rd //Only EIP has changed in regs

EAX=0000000b EBX=00009e00 EBP=000578ac

EDX=00101b88 ECX=00101bac ESP=003ffff0

ESI=00090800 EDI=00101d5c EIP=0010010d

EFLAGS=0302 (IF=1 SF=0 ZF=0 CF=0 OF=0)

Tutor> md 200 //Check mem–yes, 0b now in 0x200

00000200 0b 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….

Tutor> t //Execute int $3

Exception 3 at EIP=0010010e: Breakpoint

Tutor> ~q

Quit handler:

Killing process xxxx Leaving board #1

Tutor-vserver$

5. Try out remote gdb on tiny: See details in part 4 of

http://www.cs.umb.edu/~cheungr/cs341/VMWare-for-Tutor.pdf. For the VM

environment, COM1 is for remote gdb and COM2 is console.

————————————————————–

At the tutor-vserver VM, enter:

Tutor-vserver$ mtip -f tiny.lnx (always use board #1 for console)

For command help, type ~?

For help on args, rerun without args

Code starts at 0x100100

Using board # 1

(hit here)

Tutor> ~d

.Done.

Download done, setting eip to 100100

Tutor> gdb

Setting gdb dev to COM1, starting gdb (CTRL-C to abort).

<---just let it hang here -------------------------------------------------------------- In another window in your PC, run putty. Connect putty to the tutor-vserver VM’s IP address. Logon to tutor-vserver VM using the same credentials provided. -------------------------------------------------------------- Tutor-vserver$ Tutor-vserver$ gdb tiny.lnx GNU gdb (GDB) 7.0.1-debian Copyright (C) 2009 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later

This is free software: you are free to change and redistribute it.

There is NO WARRANTY, to the extent permitted by law. Type “show copying”

and “show warranty” for details.

This GDB was configured as “i486-linux-gnu”.

For bug reporting instructions, please see:

Reading symbols from /home/tuser/cs341/mp2/warmup/tiny.lnx…(no debugging

symbols found)…done.

(gdb) tar rem /dev/ttyS0 <--set gdb to talk to COM1 Remote debugging using /dev/ttyS0 0x00100100 in ?? () (gdb) set $eip=0x100100 <--set PC to point at 0x100100 (gdb) i reg eax 0xb 11 ecx 0x6a894 436372 edx 0x0 0 ebx 0x9e00 40448 esp 0x578a8 0x578a8 ebp 0x578ac 0x578ac esi 0x90800 591872 edi 0x51ffc 335868 eip 0x100100 0x100100 ps 0x302 770 cs 0x10 16 ss 0x18 24 http://www.cs.umb.edu/~cheungr/cs341/VMWare-for-Tutor.pdf ds 0x18 24 es 0x18 24 fs 0x18 24 gs 0x18 24 (gdb) x/x 0x200 0x200: 0x00000abc <--old contents of memory at 0x200 (gdb) set *(int *)0x200 = 0 <--how to "ms" with gdb (gdb) x/x 0x200 <--check results 0x200: 0x00000000 (gdb) set $eip = 0x100100 <--to run from start (gdb) x/4i 0x100100 <--examine 4 instructions 0x100100 : movl $0x8,%eax

0x100105 : addl $0x3,%eax

0x100108 : movl %eax,0x200

0x10010d : int3

(gdb) b *0x100105 <--set breakpoint at 2nd instruction Breakpoint 1 at 0x100105 (gdb) c <--continue from 0x100100 Continuing. Breakpoint 1, 0x100105 in tiny.opc () (gdb) i reg eax 0x8 8 ecx 0x6a894 436372 edx 0x0 0 ebx 0x9e00 40448 esp 0x578a8 0x578a8 ebp 0x578ac 0x578ac esi 0x90800 591872 edi 0x51ffc 335868 eip 0x100105 0x100105 ps 0x216 534 cs 0x10 16 ss 0x18 24 ds 0x18 24 es 0x18 24 fs 0x18 24 gs 0x18 24 (gdb) b *0x100108 Breakpoint 2 at 0x100108 (gdb) c Continuing. Breakpoint 2, 0x100108 in tiny.opc () (gdb) i reg eax 0xb 11 ecx 0x6a894 436372 edx 0x0 0 ebx 0x9e00 40448 esp 0x578a8 0x578a8 ebp 0x578ac 0x578ac esi 0x90800 591872 edi 0x51ffc 335868 eip 0x100108 0x100108 ps 0x202 514 cs 0x10 16 ss 0x18 24 ds 0x18 24 es 0x18 24 fs 0x18 24 gs 0x18 24 (gdb) b *0x10010d Breakpoint 3 at 0x10010d (gdb) c Continuing. Breakpoint 3, 0x10010d in tiny.opc () (gdb) i reg eax 0xb 11 ecx 0x6a894 436372 edx 0x0 0 ebx 0x9e00 40448 esp 0x578a8 0x578a8 ebp 0x578ac 0x578ac esi 0x90800 591872 edi 0x51ffc 335868 eip 0x10010d 0x10010d ps 0x302 770 cs 0x10 16 ss 0x18 24 ds 0x18 24 es 0x18 24 fs 0x18 24 gs 0x18 24 (gdb) x/x 0x200 0x200: 0x0000000b (gdb) q The program is running. Quit anyway (and kill it)? (y or n) y Tutor-vserver$ To everyone who may encounter this problem and ask: Question: Why I am I getting these error messages? u18(9)% cat tiny.s # tiny.s # mp2 Warmup movl $8, %eax addl $3, %eax movl %eax, 0x200 int $3 .end u18(10)% i386-as -o tiny.opc tiny.s tiny.s: Assembler messages: tiny.s:4: Error: Rest of line ignored. First ignored character valued 0xd. tiny.s:5: Error: invalid character (0xd) in second operand tiny.s:6: Error: invalid character (0xd) in second operand tiny.s:7: Error: invalid character (0xd) in second operand tiny.s:8: Error: invalid character (0xd) in first operand tiny.s:9: Error: Rest of line ignored. First ignored character valued 0xd. Answer: You must have used an editor such as notepad on your PC locally to create the .s file and used file transfer to put it on the ulab system. Notepad has put a carriage return character 0x0d at the end of each line in addition to the normal UNIX end of line character 0x0a. Here is a dump of the ASCII characters that are in your source file: u18(56)% od -x tiny.s 0000000 2320 7469 6e79 2e73 0d0a 2320 4761 6c69 0000020 6e61 204f 736d 6f6c 6f76 736b 6179 610d 0000040 0a23 206d 7032 2057 6172 6d75 700d 0a0a 0000060 2020 206d 6f76 6c20 2438 2c20 2565 6178 0000100 0a20 2020 6164 646c 2024 332c 2025 6561 0000120 780a 2020 206d 6f76 6c20 2565 6178 2c20 0000140 3078 3230 300a 2020 2069 6e74 2024 330a 0000160 2020 2e65 6e64 0a00 0000167 u18(57)% Notice the 0d0a character sequence that occurs at the end of each line. The assembler is not ignoring the carriage return character 0x0d at the end of each line. I was not aware of this as a problem that would occur with files transferred from a PC and i386-as, but it is easy to fix. You can use a UNIX editor such as vi to remove the carriage return characters OR You can use the UNIX command tr to remove the 0x0d character u18(58)% tr -d '\015' output_file

Doing either of the above should take care of your problem.