Showing posts with label Ubuntu. Show all posts
Showing posts with label Ubuntu. Show all posts

Tuesday, December 10, 2013

Linux assembler, 64 bit, for beginners

Huge majority of literature about programming in assembly is written for 32 bit architecture. So beginner will have difficulties translating and linking examples on 64 bit machine. To be more precise the first major hurdle is calling C function printf. That goes from notorious error message “Accessing a corrupted shared library” to different calling convention. To solve linking problem we need to link using 64 bit version of ld-linux.so.2. For example Richard Bloom gives following solution:

ld --dynamic-linker /lib/ld-linux.so.2 -o [name] -lc [name].o

When we apply it we have “Accessing a corrupted shared library”. I am using Linux Mint 13, based on Ubuntu 12.04, and /lib/ld-linux.so.2 is symlink to 32 bit library:

$ ls -l /lib/ld-linux.so.2
lrwxrwxrwx 1 root root 25 Sep 30 16:38 /lib/ld-linux.so.2 -> i386-linux-gnu/ld-2.15.so


Since we are on 64 bit architecture we need to modify linking to use appropriate architecture:

ld --dynamic-linker /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 -o [name] -lc [name].o

That should eliminate “Accessing a corrupted shared library” problem. Now we have calling printf problem. On 32 bit architecture we simply push on the stack parameters and on 64 bit machine that just doesn’t work. Calling convention for 64 bit architecture is the following: result will end up in %rax, parameters, in order of appearance, will go into %rdi, %rsi, %rdx, %rcx and so on. There is quite good article about it GNU x86_64 assembler - Calling printf by Aleksandar Mitrevski. Now we can try some Hello World examples.

.section .data
hws: 
    .asciz "Hello World!\n"
.section .text
.globl _start
_start:
    mov $hws, %rdi
    call printf 
    call exit


We place our zero terminated string into register %rdi and call printf. To compile, link and execute we execute the following from terminal:

$ as -o helloworld.o helloworld.s
$ ld --dynamic-linker /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 -o helloworld -lc helloworld.o
$ ./helloworld


Now slightly more complicated example:

.section .data
whatever:
    .int 1234
format:
    .asciz "Our integer is %d\n"
.section .text
.globl _start
_start:
    movq whatever, %rsi
    movq $format, %rdi
    movq $0, %rax
    call printf
    movl $1, %eax
    movl $0, %ebx
    int $0x80


The last three lines can be replaced with call exit, but this is more like examples from book Professional assembly language by Richard Blum. Final example with even more parameters and some addition:

.section .data
a:
    .int 1234
b:
    .int 766
format:
    .asciz "%d + %d = %d\n"
.section .text
.globl _start
_start:
    movq a, %rsi
    movq b, %rdx
    movq $format, %rdi
    movq %rsi, %rcx
    addq %rdx, %rcx
    movq $0, %rax
    call printf
    call exit


If you managed to build and execute all three examples, quickly go and update your CV with freshly acquired assembly on Linux experience.

Saturday, November 24, 2012

Install Oracle JDK in LinuxMint Maya or Ubuntu 12.04 LTS

This primarily describes setup required for Android development on 64 bit LinuxMint Maya what is very much the same as Ubuntu 12.04 but with usable window manager. For those two popular distros we have OpenJDK in repository and we can easily install it using apt-get from terminal or GUI Software Manager. But for Android development only Oracle JDK is supported and Android SDK is 32 bit what implies:

sudo apt-get install ia32-libs

Otherwise we will get confusing error message that for example adb was not found and we attempted to run it.
Current version of Oracle JDK can be downloaded from here http://www.oracle.com/technetwork/java/javase/downloads/index.html
For example we select jdk-7u7-linux-x64.tar.gz accept license and download it using Firefox. When download finishes we typically check signature of it and that is done from terminal, so cd to Downloads and run:

$ md5sum jdk-7u7-linux-x64.tar.gz
15f4b80901111f002894c33a3d78124c  jdk-7u7-linux-x64.tar.gz


Here I do Google search on md5 to be sure that I downloaded right archive. Then we unpack archive simply right clicking on it and selecting Extract Here. That creates directoru jdk1.7.0_07 in Downloads. JDK should be in /usr/lib/jvm unless we want to specify execution path every time, for example this is how it looks on my box:

/usr/lib/jvm $ ls -l
total 20
lrwxrwxrwx 1 root root   24 Oct 31 15:39 default-java -> java-1.6.0-openjdk-amd64
lrwxrwxrwx 1 root root   24 Oct 31 15:39 java-1.6.0-openjdk -> java-1.6.0-openjdk-amd64
lrwxrwxrwx 1 root root   20 Oct 31 15:39 java-1.6.0-openjdk-amd64 -> java-6-openjdk-amd64
lrwxrwxrwx 1 root root   24 Oct 31 15:39 java-6-openjdk -> java-1.6.0-openjdk-amd64
drwxr-xr-x 7 root root 4096 Nov  4 00:00 java-6-openjdk-amd64
drwxr-xr-x 3 root root 4096 May  3  2012 java-6-openjdk-common
lrwxrwxrwx 1 root root   24 Nov  1 11:26 java-6-oracle -> /usr/lib/jvm/jdk1.6.0_37
drwxr-xr-x 5 root root 4096 May  3  2012 java-7-openjdk-amd64
lrwxrwxrwx 1 root root   24 Oct 31 16:52 java-7-oracle -> /usr/lib/jvm/jdk1.7.0_07
drwxr-xr-x 8 root root 4096 Nov  1 11:22 jdk1.6.0_37
drwxr-xr-x 8 root root 4096 Aug 29 03:12 jdk1.7.0_07


In order to move jdk1.7.0_07 from downloads we can use

sudo mv jdk1.7.0_07 /usr/lib/jvm/

we are doing that from terminal in Downloads, or maybe start caja or gnome as root and do it from GUI. If we are in GUI we recursively change ownership to root using properties and if we are doing it from terminal:

sudo chown -R root:root /usr/lib/jvm/jdk1.7.0_07

Now we need symlink which we use later to switch between different versions of Java:

sudo ln -s /usr/lib/jvm/jdk1.7.0_07 /usr/lib/jvm/java-7-oracle

now we can install runtime and compiler:

sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/java-7-oracle/jre/bin/java 2
sudo update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/java-7-oracle/bin/javac 1


That allows us to configure runtime and compiler respectively using the following two:

sudo update-alternatives --config java
sudo update-alternatives --config javac


we need simply to type number of desired version and hit enter. To check what we are actually running we can execute:

javac -version
java -version