日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

MIPS内联汇编

發(fā)布時(shí)間:2023/12/10 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MIPS内联汇编 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

0X0

近幾天使用內(nèi)聯(lián)匯編來完成部分功能,下面總結(jié)下基礎(chǔ)知識(shí)點(diǎn),以便以后查詢

語法基本結(jié)構(gòu)

__asm__ __volatile__("匯編語句\n\t""匯編語句\n\t":輸出寄存器:輸入寄存器:寄存器破壞表);

‘:’把內(nèi)聯(lián)匯編分割為了4個(gè)部分

  • 第一部分

    如上的第二、第三行,這里可以填寫若干條匯編指令

  • 第二部分

    如上的第四行,在這里對(duì)輸出寄存器進(jìn)行描述

  • 第三部分

    如上的第五行,在這里對(duì)輸入寄存器進(jìn)行描述

  • 第四部分

    如上的第六行,

如果有輸入沒有輸出第五行的‘:’是必不可少的,是格式的一部分,第六行的‘:’可以省略
如果沒有輸出和輸入的話’:'可以省略

寄存器修飾

修飾說明
=該寄存器只寫的
+該寄存器是讀寫的
&該寄存器不能被再用作輸入寄存器
r通用寄存器
f浮點(diǎn)寄存器
moffset為有符號(hào)12bit內(nèi)存地址
ZCoffset為有符號(hào)16bit,4字節(jié)對(duì)齊地址
ZBoffset為0的地址

實(shí)例

  • 例1

    int a=2,b=1,c=0;__asm__ __volatile__("addu %0, %1, %2\n\t":"=r"(c):"r"(a),"r"(b));printf("%d \n", c);

    MIPS 無符號(hào)32位加法指令的格式為ADDU rd, rs, rt,計(jì)算rs+rt=rd,所以rd是輸出寄存器,rs、rt為輸出寄存器

    • 第三行使用%+數(shù)字來進(jìn)行占位,然后在第二、第三部分對(duì)寄存器進(jìn)行描述,并與C語言變量關(guān)聯(lián)起來

    • 第四行"=r"( c ) 是對(duì)%0的修飾,表示%0 操作數(shù)是一個(gè)通用寄存器,只寫,“寫的值放到變量c”

    • 第五行"r"(a),“r”(b),表示%1、%2操作數(shù)是通用寄存器,寄存器的值使用變量a、b的值

    對(duì)這段代碼反匯編:

    ;-- main:;-- section..text:;-- .text:;-- _ftext:0x1200008d0 f0ffbd67 daddiu sp, sp, -0x10 ; [11] -r-x section size 608 named .text0x1200008d4 0000bcff sd gp, (sp)0x1200008d8 02001c3c lui gp, 20x1200008dc c0839c67 daddiu gp, gp, -0x7c400x1200008e0 0800bfff sd ra, 8(sp)0x1200008e4 2de09903 daddu gp, gp, t90x1200008e8 02000524 addiu a1, zero, 20x1200008ec 01000224 addiu v0, zero, 10x1200008f0 2128a200 addu a1, a1, v00x1200008f4 488084df ld a0, -segment.LOAD0(gp) ; [0x120010cd8:8]=0x120000000 segment.ehdr0x1200008f8 988099df ld t9, -sym._MIPS_STUBS(gp) ; [0x120010d28:8]=0x120000b30 sym.imp.printf0x1200008fc 09f82003 jalr t90x120000900 900b8464 daddiu a0, a0, 0xb900x120000904 0800bfdf ld ra, 8(sp)0x120000908 0000bcdf ld gp, (sp)0x12000090c 25100000 move v0, zero0x120000910 0800e003 jr ra0x120000914 1000bd67 daddiu sp, sp, 0x100x120000918 00000000 nop0x12000091c 00000000 nop

    可以看到在第11~13行

    addiu a1, zero, 2 把2裝到a1寄存器

    addiu v0, zero, 1把1裝到v0寄存器

    addu a1, a1, v0把1+2結(jié)果放到a1寄存器

  • 例2

    在匯編語句比較多時(shí),再使用%+數(shù)字的方式來表示就容易混亂

    int ret = 0;int arg;__asm__ __volatile__ ("cpucfg %[var], %[index]":[var]"=r"(ret):[index]"r"(arg):);

    使用%[]來占位,中括號(hào)中可以填一個(gè)字符串

    這樣在匯編語句多時(shí)要方便些

  • 例3

    在遇到某些匯編指令編譯器不支持時(shí)可以使用二進(jìn)制編碼

    int a=0;__asm__ __volatile__(".insn \n\t"".word (0b1011100100000110010010000100) \n\t":"+r"(a):);

在C語言定義變量時(shí)也可以指定變量放在那個(gè)寄存器,如下

register int a asm("$4") = 2;

定義了一個(gè)int類型的變量,值為2,并使用的是$4寄存器

總結(jié)

以上是生活随笔為你收集整理的MIPS内联汇编的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。