Understanding the Basics
From the wiki entry of MIPS architecture, it is described as,
MIPS (originally an acronym for Microprocessor without Interlocked
Pipeline Stages) is a reduced instruction set computer (RISC)
instruction set (ISA) developed by MIPS Technologies (formerly MIPS
Computer Systems, Inc.).
From the wiki entry of the x86-64, it is described as,
x86-64 (also known as x64, x86_64 and AMD64) is the 64-bit version of
the x86 instruction set.
So as per the arch
output in the question, it is evident that I have a x86_64 machine and I try to produce the MIPS architecture specific code after running gcc
compiler.
This is similar to trying and running a diesel car on a petrol engine. No matter how hard we try, without tweaking the gas engine, we could not run the diesel car on a petrol engine.
To describe it in a technical manner, gcc
can produce assembly code for a large number of architectures, include MIPS. But what architecture a given gcc
instance targets is decided when gcc
itself is compiled. The precompiled binary you will find in an Ubuntu system knows about x86 (possibly both 32-bit and 64-bit modes) but not MIPS.
How to compile a C program to MIPS assembly code
Again quoting from the same answer, compiling gcc
with a target architecture distinct from the architecture on which gcc
itself will be running is known as preparing a cross-compilation toolchain. Or in layman's terms, this cross compilation toolchain is similar to tweaking the petrol engine to run the diesel car.
However, setting up a cross-compilation toolchain is quite a bit of work, so rather than describe how to set that up, I will describe how to install a native MIPS compiler into a MIPS virtual machine. This involves the additional steps of setting up an emulator for the VM and installing an OS into that environment, but will allow you to use a pre-built native compiler rather than compiling a cross compiler.
We will be first installing qemu
to make our system run some virtualized operating systems. Again there are several approaches like installing some cross compiled tool chain as discussed here and using a buildroot as suggested in the answer that I earlier linked.
- Download the tar ball of qemu from here.
After downloading the tar ball, run the following commands.
bzip2 -d qe*
tar -xvf qe*
./configure
make
make install
- Now, after installing
qemu
on the machine, I tried several methods
of netboot for the debian OS as suggested over
here and
here. But
unfortunately I was not able to perform the debian OS installation
using the netboot because the correct mirrors were not available.
I got an image for debian which targets MIPS architecture from
here and I
downloaded the kernel
and qemu
image and from the above link and performed the below steps.
I started the qemu
as below.
qemu-system-mips -M malta -kernel vmlinux-2.6.32-5-4kc-malta -hda
debian_squeeze_mips_standard.qcow2 -append "root=/dev/sda1 console=tty0"
After the debian system came up, I installed the gcc
compiler as
below.
apt-get update && apt-get upgrade
apt-get install build-essential
Now, I have a perfectly working native gcc
compiler inside the MIPS debian virtual machine on qemu, which compiles my C program to MIPS specific assembly code.
Testing
Inside my debian machine, I just put in a sample C hello world program and saved it as hello.c
as below.
#include<stdio.h>
int main()
{
printf("Hello World");
}
To generate MIPS architecture code for my hello.c program, I ran the C program using the gcc
compiler as,
gcc -O2 -S -c hello.c
The above command generated a hello.s
file which generated my MIPS architecture code.
.file 1 "hello.c"
.section .mdebug.abi32
.previous
.gnu_attribute 4, 1
.abicalls
.section .rodata.str1.4,"aMS",@progbits,1
.align 2
$LC0:
.ascii "Hello World\000"
.text
.align 2
.globl main
.set nomips16
.ent main
.type main, @function
main:
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
.mask 0x00000000,0
.fmask 0x00000000,0
.set noreorder
.set nomacro
lui $28,%hi(__gnu_local_gp)
addiu $28,$28,%lo(__gnu_local_gp)
lui $4,%hi($LC0)
lw $25,%call16(printf)($28)
nop
jr $25
addiu $4,$4,%lo($LC0)
.set macro
.set reorder
.end main
.size main, .-main
.ident "GCC: (Debian 4.4.5-8) 4.4.5"
But how will I know if the above generated code is MIPS assembly code?
The arch
command's output will tell the machine's architecture. In my debian machine, it produces the output as mips
and I also do not have any binutils
or cross-compiler tool chains installed in the machine.
So, the generated assembly code is MIPS specific.
Best Answer
.1
,..1
have no special meaning. They're simple identifiers (labels, variables, etc). Unless declared with.globl
, they will be local by default.That was the case then and is still the case now. For instance,
gcc
is using.
to prevent static variables from conflicting with symbols defined by the user.It assigns to the local symbol named
.3
the value of the location counter (the offset within the current segment).