How do you copy a machine instruction to a register by just using shift, or, ori? - mips32

I've been trying to learn assembly language (MIPS32) on my own, and I've been following this free online curriculum that teaches it.
There's an exercise that asks me to copy ori $8, $6, 0x20 into $9 by using only or, ori, and shift. Unfortunately, an answer isn't provided, and I have no idea how to do this. Can somebody help me or point me in the right direction? Thank you.

First you have to inspect the format used for the ori instruction:
0011 01ss ssst tttt iiii iiii iiii iiii
Source: MIPS Instruction Reference
sssss the destination register which is $8 = 01000
ttttt the source register which is $6 = 00110
ii... the immediate operand which is 0x20 = ...10 0000
The resulting instruction looks as follows:
0011 01ss ssst tttt iiii iiii iiii iiii
0011 0101 0000 0110 0000 0000 0010 0000
Which we convert to hexadecimal for use in our code: 0x35060020
Since the ori instruction accepts 16 bits for an immediate operand we can combine it with a simple left-shift to populate the higher 16 bits first with 0x3506 and then add the lower 16 bits with another ori instruction.
ori $9, $0, 0x3506 # insert upper 16 bits of instruction
# 0000 0000 0000 0000 0011 0101 0000 0110
sll $9, $9, 0x10 # shift 16 bits to higher part of register
# 0011 0101 0000 0110 0000 0000 0000 0000
ori $9, $9, 0x0020 # insert lower 16 bits of instruction
# 0011 0101 0000 0110 0000 0000 0010 0000

Related

Undefined reference to symbol in hand-written ELF file

I have hand-written an ELF32 object file that I would like to link via. gcc but I get an undefined reference when I try to use my function/label. I have it defined in a test C file as extern yet this does not change anything.
This object file contains the following assembly:
00000000 <func>:
0: 31 c0 xor %eax,%eax
2: 40 inc %eax
3: b3 2a mov $0x2a,%bl
5: cd 80 int $0x80
What you see here is the output from objdump -S test.o which shows that objdump is very much capable of finding my .text section.
My readelf output is:
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: Intel 80386
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 128 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 40 (bytes)
Number of section headers: 5
Section header string table index: 1
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .shstrtab STRTAB 00000000 000034 000021 00 0 0 1
[ 2] .text PROGBITS 00000000 000060 000007 00 AX 0 0 16
[ 3] .strtab STRTAB 00000000 000070 00000d 00 0 0 1
[ 4] .symtab SYMTAB 00000000 000150 000040 10 3 4 4
Symbol table '.symtab' contains 4 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 FILE LOCAL DEFAULT ABS test.S
2: 00000000 0 SECTION LOCAL DEFAULT 2
3: 00000000 0 NOTYPE GLOBAL DEFAULT 2 func
Which furthermore shows I have a valid symbol table and sections.
My question is, what are the exact conditions for an undefined reference to occur? What have I done incorrectly here that could lead to such an error? Is alignment for every section imperative? I've mostly done that already.
I have my symbol set to global, it is found by these two ELF analysis programs yet GCC still fails to recognise the symbol...
Here is the dump of the ELF file:
00000000: 7f45 4c46 0101 0100 0000 0000 0000 0000 .ELF............
00000010: 0100 0300 0100 0000 0000 0000 0000 0000 ................
00000020: 8000 0000 0000 0000 3400 0000 0000 2800 ........4.....(.
00000030: 0500 0100 002e 7368 7374 7274 6162 002e ......shstrtab..
00000040: 7465 7874 002e 7374 7274 6162 002e 7379 text..strtab..sy
00000050: 6d74 6162 0000 0000 0000 0000 0000 0000 mtab............
00000060: 31c0 40b3 2acd 8000 0000 0000 0000 0000 1.#.*...........
00000070: 0066 756e 6300 7465 7374 2e53 0000 0000 .func.test.S....
00000080: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000090: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000000a0: 0000 0000 0000 0000 0100 0000 0300 0000 ................
000000b0: 0000 0000 0000 0000 3400 0000 2100 0000 ........4...!...
000000c0: 0000 0000 0000 0000 0100 0000 0000 0000 ................
000000d0: 0b00 0000 0100 0000 0600 0000 0000 0000 ................
000000e0: 6000 0000 0700 0000 0000 0000 0000 0000 `...............
000000f0: 1000 0000 0000 0000 1100 0000 0300 0000 ................
00000100: 0000 0000 0000 0000 7000 0000 0d00 0000 ........p.......
00000110: 0000 0000 0000 0000 0100 0000 0000 0000 ................
00000120: 1900 0000 0200 0000 0000 0000 0000 0000 ................
00000130: 5001 0000 4000 0000 0300 0000 0400 0000 P...#...........
00000140: 0400 0000 1000 0000 0000 0000 0000 0000 ................
00000150: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000160: 0600 0000 0000 0000 0000 0000 0400 f1ff ................
00000170: 0000 0000 0000 0000 0000 0000 0300 0200 ................
00000180: 0100 0000 0000 0000 0000 0000 1000 0200 ................
I've tried already to change the function name, NOTYPE to FUNC and giving the symbol a size, yet nothing fixes the issue. The layout of the symbol table is exactly as my NASM-generated file gives me.
Edit: The file that I am trying to link with my ELF is giving the error:
/usr/bin/ld: foo.o: in function `main':
foo.c:(.text+0x18): undefined reference to `func'
collect2: error: ld returned 1 exit status
from running gcc -m32 foo.o test.o
Source code:
extern void func();
int
main(int argc,
char **argv)
{
func();
return 0;
}
And symbol table of this file after gcc -m32 -c foo.c -o foo.o:
Symbol table '.symtab' contains 15 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 FILE LOCAL DEFAULT ABS foo.c
2: 00000000 0 SECTION LOCAL DEFAULT 2
3: 00000000 0 SECTION LOCAL DEFAULT 4
4: 00000000 0 SECTION LOCAL DEFAULT 5
5: 00000000 0 SECTION LOCAL DEFAULT 6
6: 00000000 0 SECTION LOCAL DEFAULT 8
7: 00000000 0 SECTION LOCAL DEFAULT 9
8: 00000000 0 SECTION LOCAL DEFAULT 10
9: 00000000 0 SECTION LOCAL DEFAULT 7
10: 00000000 0 SECTION LOCAL DEFAULT 1
11: 00000000 38 FUNC GLOBAL DEFAULT 2 main
12: 00000000 0 FUNC GLOBAL HIDDEN 6 __x86.get_pc_thunk.ax
13: 00000000 0 NOTYPE GLOBAL DEFAULT UND _GLOBAL_OFFSET_TABLE_
14: 00000000 0 NOTYPE GLOBAL DEFAULT UND func
The error is best understood by using lld to perform the link:
ld.lld -m elf_i386 -e main main.o test.o
ld.lld: error: test.o: non-local symbol (3) found at index < .symtab's sh_info (4)
From the Solaris Linker docs:
In each symbol table, all symbols with STB_LOCAL binding precede the weak
and global symbols. As "Sections" describes, a symbol table section's sh_info
section header member holds the symbol table index for the first non-local symbol.
You must set .symtabs .sh_info to 3, and then your test.o will work.

BaseOfCode present in PE+ executable

The MS documentation says that the BaseOfCode value is only present in PE files, not in PE+. Looking at notepad.exe with dotPeek and with PE Viewer seems to indicate that the BaseOfCode is present and consumed.
0 1 2 3 4 5 6 7 8 9 A B C D E F
0x00E0 | 5045 0000 6486 0600 6a98 8957 0000 0000
0x00F0 | 0000 0000 f000 2200 0b02 0e00 0086 0100
0x0100 | 004e 0200 0000 0000 d087 0100 0010 0000
The two bytes at 0x00F8 signify that this is a PE+ header. The BaseOfCode is the four bytes at 0x010C.
Is the documentation (and myself) incorrect or are dotPeek and PE View
incorrect?
The fact that these bytes aren't zeroed out would imply that it the bytes are significant in some way.

How to generate 2 pixel BMP image with Awk?

sorry for the silly question, but I'm trying to create (generate) a simple BMP image 2x1, 24-bit bitmap with pixel format RGB24, using Awk.
Format is "BitmapFileHeader (2+4+4+4=14 bytes) + DIBHeader (4+4+4+2+2+4+4+4+4+4+4=40 bytes) = 54byte", then start of pixel array (bitmap data). Here is my simple script:
BEGIN {
ORS="";
filebmp="Image.bmp"
# BMP Header: 2+4+4+4=14 bytes
printf("%c%c",66,77)>filebmp;
printf("%c%c%c%c",62,0,0,0)>filebmp;
printf("%c%c%c%c",0,0,0,0)>filebmp;
printf("%c%c%c%c",54,0,0,0)>filebpm;
# DIB Header: 4+4+4+2+2+4+4+4+4+4+4=40 bytes
printf("%c%c%c%c",40,0,0,0)>filebmp;
printf("%c%c%c%c",2,0,0,0)>filebmp;
printf("%c%c%c%c",1,0,0,0)>filebmp;
printf("%c%c",1,0)>filebmp;
printf("%c%c",24,0)>filebmp;
printf("%c%c%c%c",0,0,0,0)>filebmp;
printf("%c%c%c%c",8,0,0,0)>filebmp;
printf("%c%c%c%c",19,11,0,0)>filebmp;
printf("%c%c%c%c",19,11,0,0)>filebmp;
printf("%c%c%c%c",0,0,0,0)>filebmp;
printf("%c%c%c%c",0,0,0,0)>filebmp;
# start of pixel array (bitmap data)
# Blu pixel
printf ("%c%c%c",127,0,0)>filebmp;
# Green pixel
printf ("%c%c%c",0,127,0)>filebmp;
# Padding
printf ("%c%c",0,0)>filebmp;
}
it's works (image below): it generates a BMP image 2x1 and 62 byte size.
http://i60.tinypic.com/mlihyt.jpg
But, now, if in the bitmap data I substitute 127 value with 128 (e.g. in blue pixel), same script Awk generates a BMP image 2x1 but 63 byte size and with "other colours" (see image below)!
http://i62.tinypic.com/2ltkjlg.png
I wonder where I am going wrong...
...any ideas?
Thanks & Bye
I was able to reproduce the issue with gawk. It seems that gawk chooses the output encoding based on your LANG environment variable. (Here I've change both instances of 127 to 128.)
$ LANG=en_US.LATIN1 gawk -f bit.awk
$ wc -c Image.bmp
62 Image.bmp
00000000: 424d 3e00 0000 0000 0000 3600 0000 2800 BM>.......6...(.
00000010: 0000 0200 0000 0100 0000 0100 1800 0000 ................
00000020: 0000 0800 0000 130b 0000 130b 0000 0000 ................
00000030: 0000 0000 0000 8000 0000 8000 0000 ..............
$ LANG=en_US.UTF-8 gawk -f bit.awk
$ wc -c Image.bmp
64 Image.bmp
00000000: 424d 3e00 0000 0000 0000 3600 0000 2800 BM>.......6...(.
00000010: 0000 0200 0000 0100 0000 0100 1800 0000 ................
00000020: 0000 0800 0000 130b 0000 130b 0000 0000 ................
00000030: 0000 0000 0000 c280 0000 00c2 8000 0000 ................
Run gawk under a single-byte encoding and you should be fine.

Use bitwise AND with string on ruby on rails

I want use bitwise operator "&" with string like that :
raw_counter_int = raw_counter.to_i
raw_counter_bin = raw_counter_int.to_s(2)
u = (2**62 + 2**63)
k = u.to_s(2)
r = raw_counter_bin & k
#counter_msg = r
but when I run my application I've this error message :
undefined method `&' for "10000000000000000000000000000000000000000000000000000000":String
How I can use this operator "&" with raw_counter_int and u which are converted in binary ?
I try with this: 0000 0000 1000 0000 0000 0000 0000 0000 (64 bits) to
take bytes between the third bytes and the 10th bytes. So I want do a
bitwise "&" with 0000 0000 1000 0000 0000 0000 0000 0000 & 0011 1111
1100 0000 0000 0000 0000 0000 to take just this : 00 0000 10
I try with this: 0000 0000 1000 0000 0000 0000 0000 0000 (64 bits) to
take bytes between the third bytes and the 10th bytes. So I want do a
bitwise "&" with 0000 0000 1000 0000 0000 0000 0000 0000 & 0011 1111
1100 0000 0000 0000 0000 0000 to take just this : 00 0000 10
Let's do it:
("00000000100000000000000000000000".to_i(2) & "00111111110000000000000000000000".to_i(2)).to_s(2)
=> "100000000000000000000000"
Which is exactly what is expected! The number shown in the error ("10000000000000000000000000000000000000000000000000000000") is 2^56, which, when using bitwise AND with it and 2^62+2^63 is expected to give you a zero result...
I suggest you check your input again, and trust ruby's & to do the job...

awk instead of sed is not working (slow, laggy and wrong output)

Why is awk not working for the following command instead of sed:
su -c "stdbuf -i0 -o0 -e0 od --width=144 -x /dev/input/event3 | sed 's%^\([a-z0-9]\+ \)\{11\}%%;s%\(....\).*%\1%'"
This prints at every keypress the USB HID ID number of the key that was pressed.
Example output (0028 is for Return and 00e4 for Right-Ctrl):
0028
0028
0028
0028
0028
00e4
00e4
00e4
This are two lines of output without sed/cut/awk filtering when pressing Return two times. The USB HID ID number is in column 12:
0000000 2d6f 511e 0000 0000 051b 0007 0000 0000 0004 0004 0028 0007 2d6f 511e 0000 0000 051d 0007 0000 0000 0001 001c 0000 0000 2d6f 511e 0000 0000 051e 0007 0000 0000 0000 0000 0000 0000 2d73 511e 0000 0000 a150 0007 0000 0000 0004 0004 0028 0007 2d73 511e 0000 0000 a153 0007 0000 0000 0001 001c 0001 0000 2d73 511e 0000 0000 a154 0007 0000 0000 0000 0000 0000 0000
0000220 2d73 511e 0000 0000 9b5a 0008 0000 0000 0004 0004 0028 0007 2d73 511e 0000 0000 9b5d 0008 0000 0000 0001 001c 0000 0000 2d73 511e 0000 0000 9b5e 0008 0000 0000 0000 0000 0000 0000 2d74 511e 0000 0000 4f90 0005 0000 0000 0004 0004 0028 0007 2d74 511e 0000 0000 4f93 0005 0000 0000 0001 001c 0001 0000 2d74 511e 0000 0000 4f94 0005 0000 0000 0000 0000 0000 0000
I tried it with
su -c "stdbuf -i0 -o0 -e0 od --width=144 -x /dev/input/event3 | cut -d' ' -f12"
and it also works. But it only shows the keys pressed after the next two keypresses. stdbuf did not help here, although it should adjusts standard input/output/error stream buffering to 0.
My mawk command looked like this:
su -c "stdbuf -i0 -o0 -e0 od --width=$((48*3)) -x /dev/input/event3 | mawk '{ print $12 }'"
but it only showed me some twos and then some newlines and again twos. It seems very laggy/slow. When I press a key, nothing happens. After pressing different keys multiple times, I always get a bunch of twos and newlines. No matter which keys I pressed! Example:
2
2
2
2
2
2
2
2
2
2
2
2
How can I fix this? Why is this occurring?
Update
When I use gawk instead of mawk it does not lag any more (unbuffered). But I still don’t see the correct values which should be 0028 or 00e4 and so on for Return and Right-Ctrl as example keys.
With all the comments I came to the solution.
#Olivier Dulac brought me to the idea that there are different awk implementations, which solved the problem of the laggyness (using gawk instead of mawk). I don’t even need the stdbuf.
#Ed Morton’s idea brought me to a problem, because he used quotes " in his example. I already had quotes in my statement around the whole thing, because it was executed using su. So I had to escape them.
My whole statement looks like this (notice the escaped dollar sign in front of the 12):
su -c "od --width=144 -x /dev/input/event3 | awk '{ print \$12 }'"
and now it works as expected.

Resources