Compiling

在 X86 機器上生成 MIPS 架構彙編程式碼

  • May 19, 2017

當我執行我的 C 程序時,我需要在我的機器上生成MIPS特定程式碼。當我簡單地跑步時,

gcc -O2 -S -c hello.c

在我的系統上,我得到了hello.s似乎生成一些彙編程式碼但它似乎不是MIPS特定程式碼。文件內容hello.s如下。

   .file   "hello.c"
   .section    .rodata.str1.1,"aMS",@progbits,1
.LC0:
   .string "Hello world"
   .text
   .p2align 4,,15
.globl main
   .type   main, @function
main:
.LFB11:
   .cfi_startproc
   movl    $.LC0, %edi
   xorl    %eax, %eax
   jmp printf
   .cfi_endproc
.LFE11:
   .size   main, .-main
   .ident  "GCC: (GNU) 4.4.7 20120313 (Red Hat 4.4.7-4)"
   .section    .note.GNU-stack,"",@progbits

如何在我的機器上生成MIPS特定程式碼?

我的機器詳細資訊如下。

arch
x86_64

了解基礎知識


從 MIPS 架構的wiki條目中,它被描述為,

MIPS(最初是 Microprocessor without Interlocked Pipeline Stages 的首字母縮寫詞)是由 MIPS Technologies(前身為 MIPS Computer Systems, Inc.)開發的精簡指令集電腦 (RISC) 指令集 (ISA)。

從 x86-64 的wiki條目中,它被描述為,

x86-64(也稱為 x64、x86_64 和 AMD64)是 x86 指令集的 64 位版本。

因此,根據arch問題中的輸出,很明顯我有一台x86_64機器,並且我嘗試在執行編譯器後生成MIPS體系結構特定的程式碼。gcc

這類似於嘗試在汽油發動機上執行柴油車。無論我們多麼努力,如果不調整燃氣發動機,我們就無法在汽油發動機上執行柴油車。

用技術的方式來描述它gcc可以產生大量架構的彙編程式碼,包括MIPS。但是,給定gcc實例的目標架構是在gcc編譯時決定的。您將在 Ubuntu 系統中找到的預編譯二進製文件了解x86(可能同時具有 32 位和 64 位模式),但不了解MIPS


如何將 C 程序編譯為 MIPS 彙編程式碼


再次引用相同的答案,使用與自身將執行gcc的架構不同的目標架構進行gcc編譯稱為準備交叉編譯工具鏈。或者用外行的話來說,這個交叉編譯工具鏈類似於調整汽油發動機來執行柴油車

然而,設置一個交叉編譯工具鍊是一項相當多的工作,所以我將描述如何將一個本地 MIPS 編譯器安裝到 MIPS 虛擬機中,而不是描述如何設置它。這涉及為 VM 設置模擬器並將作業系統安裝到該環境中的額外步驟,但將允許您使用預建構的本機編譯器而不是編譯交叉編譯器。

我們將首先安裝qemu以使我們的系統執行一些虛擬化作業系統。同樣有幾種方法,比如安裝一些交叉編譯的工具鏈,如這裡討論的,並使用我之前連結的答案中建議的 buildroot。

  • 從這裡下載qemu的 tar包。
  • 下載 tar 球後,執行以下命令。
bzip2 -d qe*
tar -xvf qe*
./configure
make
make install
  • 現在,在qemu機器上安裝後,我嘗試了幾種針對 debian OS 的 netboot 方法,如此 此處所建議的那樣。但不幸的是,由於沒有正確的鏡像,我無法使用 netboot 執行 debian OS 安裝。

我從這裡獲得了一個針對 MIPS 架構的 debian 圖像, 我從上面的連結下載了kernelqemu圖像並執行了以下步驟。

  • 我開始qemu如下。
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"
  • debian系統啟動後,我安裝了gcc編譯器,如下所示。
apt-get update && apt-get upgrade
apt-get install build-essential

現在,我gcc在 qemu 上的 MIPS debian 虛擬機中有一個完美執行的本地編譯器,它將我的 C 程序編譯為MIPS特定的彙編程式碼。


測試


在我的 debian 機器中,我只是放入了一個範例 C hello world 程序並將其保存hello.c如下。

#include<stdio.h>
int main()
{
   printf("Hello World");
}

為了為我的 hello.c 程序生成 MIPS 架構程式碼,我使用gcc編譯器執行了 C 程序,

gcc -O2 -S -c hello.c

上面的命令生成了一個hello.s文件,該文件生成了我的MIPS架構程式碼。

   .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"

但是我怎麼知道上面生成的程式碼是不是MIPS彙編程式碼呢?

arch命令的輸出將告訴機器的架構。在我的 debian 機器中,它產生的輸出為mips,我也沒有binutils在機器中安裝任何或交叉編譯器工具鏈。

因此,生成的彙編程式碼是特定於MIPS的。

引用自:https://unix.stackexchange.com/questions/163241