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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Ubuntu >内容正文

Ubuntu

Ubuntu下用gcc与nasm联合编译

發布時間:2025/6/15 Ubuntu 64 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Ubuntu下用gcc与nasm联合编译 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.代碼

foo.asm

[plain] view plaincopy
  • ;編譯鏈接的方法??
  • ;(id的'-s'選項意為"strip?all")??
  • ;??
  • ;$?nasm?-f?elf?foo.asm?-o?foo.o??
  • ;$?gcc?-c?bar.c?-o?bar.o??
  • ;$?id?-s?hello.o?bar.o?foobar??
  • ;$?./foobar??
  • ;the?2nd?one??
  • ;$??
  • ??
  • extern?choose???????;int?choose(int?a,int?b)??
  • ??
  • [section?.data]?????;數據在此??
  • ??
  • num1st??dd??3??
  • num2nd??dd??4??
  • ??
  • [section?.text]?????;代碼在此??
  • ??
  • global?_start???????;我們必須導出?_start?這個入口,以便讓鏈接器識別??
  • global?myprint??????;導出這個函數為了讓bar.c使用??
  • ??
  • _start:??
  • ????push????dword?[num2nd]??;'.??
  • ????push????dword?[num1st]??;|??
  • ????call????choose??????;|choose(num1st,num2nd);??
  • ????add?esp,8???????;/??
  • ??
  • ????mov?ebx,0??
  • ????mov?eax,1???????;sys_exit??
  • ????int?0x80????????;系統調用??
  • ??
  • ;void?myprint(char*?msg,int?len)??
  • myprint:??
  • ????mov?edx,[esp?+?8]???;len??
  • ????mov?ecx,[esp?+?4]???;msg??
  • ????mov?ebx,1??
  • ????mov?eax,4???????;sys_write??
  • ????int?0x80????????;系統調用??
  • ????ret??
  • bar.c

    [plain] view plaincopy
  • void?myprint(char*?msg,int?len);??
  • ??
  • int?choose(int?a,int?b)??
  • {??
  • ????if(a>=b)?{??
  • ????????myprint("the?1st?one\n",13);??
  • ????}??
  • ????else?{??
  • ????????myprint("the?2nd?one\n",13);??
  • ????}??
  • ??
  • ????return?0;??
  • }??

  • 2.編譯連接+執行(32位)

    > ls

    bar.c? foo.asm

    > nasm -f elf32 -o foo.o foo.asm

    > gcc -m32 -c -o bar.obar.c

    > ld -m elf_i386 -s -o foobar foo.o bar.o

    > ls

    bar.c? bar.o? foo.asm? foobar? foo.o

    > ./foobar

    the 2nd one

    3.代碼解釋

    extern:EXTERN 偽操作告訴編譯器當前的符號不是在本源文件中定義的,而是在其他源文件中定義的,在本源文件中可能引用該符號。如果本源文件沒有實際引用該符號,該符號將不會被加入到本源文件的符號表中。

    global:關鍵字,把符號導出到其他模塊中。global是extern的對立面,如果一個模塊聲明一個extern的符號,然后引用它,為了防止鏈接錯誤,另外某一個模塊必須確實定義了該符號,然后把它聲明為global。

    ? 1.由于在bar.c中用到函數myprint(),所以要用關鍵字global將其導出

    ? 2.由于用到本文件外定義的函數choose(),所以要用關鍵字extern聲明

    ? 3.myprint()和choose()遵循的都是C調用約定,后面的參數先入棧,并由調用者清理堆棧

    dd:偽指令——定義雙字。其后的每個操作數占用二個字(低字在前)。 DD還可以把其后的變量或標號的偏移地址和所在段首址存入存儲器內指定 的雙字單元(即DD前面的變量)中,第一個字中存放DD后的變量的偏移地址, 第二個字中存放該變量所在段的段首址。

    push:入棧操作,遵守FILO原則(first in last out),而且必須是字操作。

    dword:是雙字,也就是32位,可以用來儲存32位整數或者32位內存地址。[拓展:byte是字節,也就是8位,用來儲存char或者char類型指針。word是字,也就是16位。用來儲存16位整數或者16位地址]

    add:操作數相加。ADD OPRD1,OPRD2。

    ? ?1.OPRD1為任一通用寄存器或存儲器操作數,可以是任意一個通用寄存器,而且還可以是任意一個存儲器操作數。
    ? ?2.OPRD2為立即數,也可以是任意一個通用寄存器操作數.立即數只能用于源操作數。
    ? ?3.OPRD1和OPRD2均為寄存器是允許的,一個為寄存器而另一個為存儲器也是允許的, 但不允許兩個都是存儲器操作數。
    ? ?4.加法指令運算的結果對CF、SF、OF、PF、ZF、AF都會有影響.以上標志也稱為結果標志.加法指令適用于無符號數或有符號數的加法運算。

    --------------------------------------------------------//32bit或64bit版本

    生成的.o文件必須都是32位或者都是64位:

    -------------------------------------gcc 命令行參數:

    -m32:生成32位代碼

    -m64:生成64位代碼

    -------------------------------------連接時版本注明:

    -m elf_i386 :32位

    -m elf_x86_64:

    -m elf32_x86_64:

    -------------------------------------編譯時版本注明:

    -f elf64:64位

    -f elf32:32位

    ---------------------------------------------------------//命令行

    -c:只編譯并生成目標文件

    ./:表示當前目錄的全路徑,一般不在系統環境變量path中的可執行文件 ,運行的時候都要這樣運行,當然寫成絕對路徑也行

    總結

    以上是生活随笔為你收集整理的Ubuntu下用gcc与nasm联合编译的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。