انجمن‌های فارسی اوبونتو

لطفاً به انجمن‌ها وارد شده و یا جهت ورود ثبت‌نام نمائید

لطفاً جهت ورود نام کاربری و رمز عبورتان را وارد نمائید


ارائه ۲۴٫۱۰ اوبونتو منتشر شد 🎉

نویسنده موضوع: استفاده از اسمبلی در C  (دفعات بازدید: 8252 بار)

0 کاربر و 2 مهمان درحال مشاهده موضوع.

آفلاین علی ۵۰۰

  • Hero Member
  • *
  • ارسال: 775
  • جنسیت : پسر
استفاده از اسمبلی در C
« : 31 فروردین 1392، 08:09 ب‌ظ »
به نام خداوند بخشنده مهربان
سلام
در کامپایلر gcc و لینوکس با زبان برنامه نویسی C چه‌طور میشه از اسمبلی استفاده کرد؟ :)
با تشکر

آفلاین محمدرضا ح.

  • High Hero Member
  • *
  • ارسال: 3117
  • جنسیت : پسر
  • Your Future is our Past!
پاسخ : استفاده از اسمبلی در C
« پاسخ #1 : 31 فروردین 1392، 08:17 ب‌ظ »
اسمبلی بصورت Inline در C نوشته میشه. و با سینتکس AT&T . و در کد C به این شکل نوشته میشه:

#asm
//put your code here
#endasm

میتونید به این شکل اسمبلی بنویسید.

میتونید جداگانه هم نوشته و توسط nasm کامپایلش کنید.
قاضی : تو السالوادور چه کار میکردی؟
چه‌گوارا : آفتاب میگرفتم
قاضی : پس چرا ساختمان دادگستری رو منفجر کردی؟
چه‌گوارا : جلوی آفتاب رو گرفته بود

آفلاین علی ۵۰۰

  • Hero Member
  • *
  • ارسال: 775
  • جنسیت : پسر
پاسخ : استفاده از اسمبلی در C
« پاسخ #2 : 01 اردیبهشت 1392، 10:40 ق‌ظ »
حالا این کدی رو که نوشتم درسته؟ اگه درسته باید چه‌طور کامپایلرش کنم؟ :)
#include <stdio.h>
int main()
{
#asm
  mov ah, 9h // function call to print
  mov bh, 0 // page number
  mov bl, 7 // attribute
  mov cx, 5 // number of print
  mov al, 03h // heart character
  int 10h // interrupt call
#endasm
getchar();
return 0;
}

آفلاین محمدرضا ح.

  • High Hero Member
  • *
  • ارسال: 3117
  • جنسیت : پسر
  • Your Future is our Past!
پاسخ : استفاده از اسمبلی در C
« پاسخ #3 : 01 اردیبهشت 1392، 01:43 ب‌ظ »
من چون اینطور ننوشتم مطمئن نیستم. فقط این کد رو بزن (با فرض اینکه اسم سورست asm.c باشه!)

gcc asm.c
فکر کنم الان اونی که منفی میده تو کمینه  ;D
قاضی : تو السالوادور چه کار میکردی؟
چه‌گوارا : آفتاب میگرفتم
قاضی : پس چرا ساختمان دادگستری رو منفجر کردی؟
چه‌گوارا : جلوی آفتاب رو گرفته بود

آفلاین محمدرضا ح.

  • High Hero Member
  • *
  • ارسال: 3117
  • جنسیت : پسر
  • Your Future is our Past!
پاسخ : استفاده از اسمبلی در C
« پاسخ #4 : 01 اردیبهشت 1392، 02:14 ب‌ظ »
asm.c: In function ‘main’:
asm.c:4:2: error: invalid preprocessing directive #asm
asm.c:5:3: error: unknown type name ‘mov’
asm.c:5:11: error: invalid suffix "h" on integer constant
asm.c:5:11: error: expected identifier or ‘(’ before numeric constant
asm.c:9:11: error: invalid suffix "h" on integer constant
asm.c:10:7: error: invalid suffix "h" on integer constant
asm.c:11:2: error: invalid preprocessing directive #endasm

خب کد مشکل داره. بهتره عبارت Inline assembly in C رو در موتورهای جست و جو سرچ کنید :)
قاضی : تو السالوادور چه کار میکردی؟
چه‌گوارا : آفتاب میگرفتم
قاضی : پس چرا ساختمان دادگستری رو منفجر کردی؟
چه‌گوارا : جلوی آفتاب رو گرفته بود

آفلاین majidkamali1370

  • Hero Member
  • *
  • ارسال: 928
  • جنسیت : پسر
پاسخ : استفاده از اسمبلی در C
« پاسخ #5 : 01 اردیبهشت 1392، 06:31 ب‌ظ »
البته نوشتن اسمبلی در C یا ++C با کلمه کلیدی asm یا asm_ یا asm__ هست. (اینکه کدومش هست رو شک دارم)
مثلا به صورت زیر:
asm mov $9, %ahیا
asm {
// multiple assembly codes
}
البته اون سیتکسی که شما نوشتی مال intel هست. سینتکس AT&T یه چیزی شبیه اینیه که من نوشتم. (احتمالا اشتباه نوشتم).
با دستور زیر کامپایل کنید.
gcc yourASM.cاگه کمی C بلد هستید، میتونید یه برنامه خیلی ساده به زبان C بنویسید و با آپشن S خروجی اسمبلی اون رو ببینید
gcc yourASM.c -Sیه فایل اسمبلی میسازه که تبدیل شده کد شما به زبون اسمبلی با سینتکس AT&T هست. اینطوری راحتتر یاد میگیرید
Ubuntu 14.04 LTS 64-bit - unity

آفلاین محمدرضا ح.

  • High Hero Member
  • *
  • ارسال: 3117
  • جنسیت : پسر
  • Your Future is our Past!
پاسخ : استفاده از اسمبلی در C
« پاسخ #6 : 01 اردیبهشت 1392، 06:37 ب‌ظ »
یک نرم افزار ساده که توسط gcc به اسمبلی تبدیل کردم :

.file "hello.c"
.section .rodata
.LC0:
.string "HelloWorld"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
andl $-16, %esp
subl $16, %esp
movl $.LC0, (%esp)
call puts
movl $0, %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2"
.section .note.GNU-stack,"",@progbits

این هم کد C :

#include <stdio.h>
int main()
{
printf("Hello World\n");
return 0;
}
قاضی : تو السالوادور چه کار میکردی؟
چه‌گوارا : آفتاب میگرفتم
قاضی : پس چرا ساختمان دادگستری رو منفجر کردی؟
چه‌گوارا : جلوی آفتاب رو گرفته بود

آفلاین majidkamali1370

  • Hero Member
  • *
  • ارسال: 928
  • جنسیت : پسر
پاسخ : استفاده از اسمبلی در C
« پاسخ #7 : 01 اردیبهشت 1392، 08:13 ب‌ظ »
در حد اطلاعات خودم این رو بهتون میگم. همه جاشو بلد نیستم.
1. این file. همونیه که توی C یا ++C اینجوری صداش میزنیم __FILE__
2. section یعنی قسمت. فایلهای اجرایی توی ۱۶ و ۳۲ بیتی از این قسمتها استفاده میکنن (در مورد ۶۴ بیت اطلاعی ندارم). هر فایل اجرایی ۴ قسمت داره.
  • قسمت متغیرهای مقدار دهی شده.
  • قسمت متغیرهای مقدار دهی نشده یا اونایی که اندازشون معلوم نیست و در آینده معلوم میشه. مثل اشاره گرها که قراره بشن آرایه
  • قسمت کد برنامه که معمولا با text نشون میدن
  • یادم نیست  ;D
3. هر تابع موقعی که میخواد کارشو شروع کنه بستگی به calling convention باید یه سری کارا رو بکنه. مثلا توی C calling convention که زبون C ازش استفاده میکنه کار خالی کردن و برگردوندن ثباتهای stack بر عهده تابع هست. اون خطوط pushl %ebp تا پنچ شش خط پایینترش هم برای همینه و همچنین دستور leave. این کارا رو باید تابع انجام بده که میبینید توی main اومده.
4. خط
movl $.LC0, (%esp)تازه قسمت اصلی اجرا میشه. از label ای که اسمش LC0 هست. آدرس اولین بایتش رو میریزه توی esp. چرا اولین بایت؟ چون چیزی با LC0.$ جمع نشده و اون متن hello world اولین متغیر اون هست.
5. در خط بعد هم تابع puts رو صدا میزنه که توی stdio هست.
6. خط
movl $0, %eaxمقدار eax رو صفر میکنه که متناظر با همون خط return 0 هست.
7. در نهایت هم مراحل خروج از تابع رو میره.

میدونم خیلی ناقصه ولی امیدوارم جاییش رو اشتباه نگفته باشم.
Ubuntu 14.04 LTS 64-bit - unity

آفلاین محمدرضا ح.

  • High Hero Member
  • *
  • ارسال: 3117
  • جنسیت : پسر
  • Your Future is our Past!
پاسخ : استفاده از اسمبلی در C
« پاسخ #8 : 01 اردیبهشت 1392، 08:19 ب‌ظ »
+۱ مجید جان :) .


@علی بهمنی جلالی :

اگر حوصله این سبک Assembly نوشتن رو نداری ، میتونی فایلهایی که با سینتکس اینتل نوشتی رو با C لینک کنی.

مثلا این یک سیستم عامل ساده هست که روش لینک کردن رو هم تا حدودی گفته :

http://wiki.osdev.org/C%2B%2B_Bare_Bones

البته این در ++C هست. ولی روش مشابه هست تا حدود زیادی.

اگر هم چیزی میخوای بین C و Assembly زبان --C (سی مینس مینس) رو پیشنهاد میدم :

http://www.cminusminus.org/index.html
قاضی : تو السالوادور چه کار میکردی؟
چه‌گوارا : آفتاب میگرفتم
قاضی : پس چرا ساختمان دادگستری رو منفجر کردی؟
چه‌گوارا : جلوی آفتاب رو گرفته بود

آفلاین محمدرضا ح.

  • High Hero Member
  • *
  • ارسال: 3117
  • جنسیت : پسر
  • Your Future is our Past!
مثال کاربردی تر از ++C و Assembly
« پاسخ #9 : 01 اردیبهشت 1392، 09:13 ب‌ظ »
این یک کد ++C هست که یک ورودی میگیره ، یک واحد بهش اضافه میکنه و در خروجی قرار میده :

#include <iostream>
using namespace std;
int main() {
int i;
cout<<"Enter A Number:";
cin>>i;
int j=++i;
cout<<"Result is :"<<j <<"\n";
return 0;
}

و این نیز کد اسمبلیش :

.file "plusone.cpp"
.local _ZStL8__ioinit
.comm _ZStL8__ioinit,1,1
.section .rodata
.LC0:
.string "Enter A Number:"
.LC1:
.string "Result is :"
.LC2:
.string "\n"
.text
.globl main
.type main, @function
main:
.LFB969:
.cfi_startproc
.cfi_personality 0,__gxx_personality_v0
.cfi_lsda 0,.LLSDA969
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
andl $-16, %esp
subl $32, %esp
movl $.LC0, 4(%esp)
movl $_ZSt4cout, (%esp)
.LEHB0:
call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
leal 24(%esp), %eax
movl %eax, 4(%esp)
movl $_ZSt3cin, (%esp)
call _ZNSirsERi
movl 24(%esp), %eax
addl $1, %eax
movl %eax, 24(%esp)
movl 24(%esp), %eax
movl %eax, 28(%esp)
movl $.LC1, 4(%esp)
movl $_ZSt4cout, (%esp)
call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
movl 28(%esp), %edx
movl %edx, 4(%esp)
movl %eax, (%esp)
call _ZNSolsEi
movl $.LC2, 4(%esp)
movl %eax, (%esp)
call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
.LEHE0:
movl $0, %eax
jmp .L5
.L4:
movl %eax, (%esp)
.LEHB1:
call _Unwind_Resume
.LEHE1:
.L5:
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE969:
.globl __gxx_personality_v0
.section .gcc_except_table,"a",@progbits
.LLSDA969:
.byte 0xff
.byte 0xff
.byte 0x1
.uleb128 .LLSDACSE969-.LLSDACSB969
.LLSDACSB969:
.uleb128 .LEHB0-.LFB969
.uleb128 .LEHE0-.LEHB0
.uleb128 .L4-.LFB969
.uleb128 0
.uleb128 .LEHB1-.LFB969
.uleb128 .LEHE1-.LEHB1
.uleb128 0
.uleb128 0
.LLSDACSE969:
.text
.size main, .-main
.type _Z41__static_initialization_and_destruction_0ii, @function
_Z41__static_initialization_and_destruction_0ii:
.LFB973:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
subl $24, %esp
cmpl $1, 8(%ebp)
jne .L6
cmpl $65535, 12(%ebp)
jne .L6
movl $_ZStL8__ioinit, (%esp)
call _ZNSt8ios_base4InitC1Ev
movl $__dso_handle, 8(%esp)
movl $_ZStL8__ioinit, 4(%esp)
movl $_ZNSt8ios_base4InitD1Ev, (%esp)
call __cxa_atexit
.L6:
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE973:
.size _Z41__static_initialization_and_destruction_0ii, .-_Z41__static_initialization_and_destruction_0ii
.type _GLOBAL__sub_I_main, @function
_GLOBAL__sub_I_main:
.LFB974:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
subl $24, %esp
movl $65535, 4(%esp)
movl $1, (%esp)
call _Z41__static_initialization_and_destruction_0ii
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE974:
.size _GLOBAL__sub_I_main, .-_GLOBAL__sub_I_main
.section .init_array,"aw"
.align 4
.long _GLOBAL__sub_I_main
.hidden __dso_handle
.ident "GCC: (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2"
.section .note.GNU-stack,"",@progbits


برای اسمبل کردنش :

as /path/to/file.s
البته نمیدونم چرا وقتی خروجی اسمبلرش رو اجرا میکنم ارور Permission Denied میده ;D
قاضی : تو السالوادور چه کار میکردی؟
چه‌گوارا : آفتاب میگرفتم
قاضی : پس چرا ساختمان دادگستری رو منفجر کردی؟
چه‌گوارا : جلوی آفتاب رو گرفته بود

آفلاین r_m1232002

  • Full Member
  • *
  • ارسال: 143
پاسخ : استفاده از اسمبلی در C
« پاسخ #10 : 01 اردیبهشت 1392، 09:16 ب‌ظ »
یک کتاب کامل در مورد اسمبلی که در اون کد های اسمبلی به صورت مجزا نوشته می شوند و توسط NASM اسمبل می شوند سپس با کد های زبان C لینک میشوند. به این ترتیب می تونید به صورت دوطرفه به C و اسمبلی دسترسی داشته باشید در حالی که اسمبلی رو با سینتکس اینتل می نویسید:

http://www.drpaulcarter.com/pcasm/

آفلاین majidkamali1370

  • Hero Member
  • *
  • ارسال: 928
  • جنسیت : پسر
پاسخ : استفاده از اسمبلی در C
« پاسخ #11 : 01 اردیبهشت 1392، 09:29 ب‌ظ »
فکر میکنم as فقط اسمبلر هست و برای گرفتن خروجی فایل اجرایی از اون برنامه باید از ld هم استفاده بشه. البته من اطلاعات دقیق ندارم.
Ubuntu 14.04 LTS 64-bit - unity

آفلاین keshavarz2440

  • Jr. Member
  • *
  • ارسال: 28
  • جنسیت : پسر
پاسخ : استفاده از اسمبلی در C
« پاسخ #12 : 01 اردیبهشت 1392، 10:25 ب‌ظ »
حوصله ای داریدا  ;D

آفلاین אוּרִיאֵל

  • High Sr. Member
  • *
  • ارسال: 641
  • جنسیت : پسر
  • bin/Matin/ !#
    • bin/Matin/ !#
پاسخ : استفاده از اسمبلی در C
« پاسخ #13 : 01 اردیبهشت 1392، 10:35 ب‌ظ »
یه سؤال میپرسم مسخره نکنین … از سی استفاده کنی کامپایل کنی فرقی داره با این که اول به اسمبلی تبدیلش کنی بعد کامپایل کنی ؟؟؟!!!… البته به جز در مورد سرعت کامپایل بیشتر منظورم بعد از کامپایله …

آفلاین محمدرضا ح.

  • High Hero Member
  • *
  • ارسال: 3117
  • جنسیت : پسر
  • Your Future is our Past!
پاسخ : استفاده از اسمبلی در C
« پاسخ #14 : 01 اردیبهشت 1392، 10:36 ب‌ظ »
یه سؤال میپرسم مسخره نکنین … از سی استفاده کنی کامپایل کنی فرقی داره با این که اول به اسمبلی تبدیلش کنی بعد کامپایل کنی ؟؟؟!!!… البته به جز در مورد سرعت کامپایل بیشتر منظورم بعد از کامپایله …

راستش رو بخوای به asm تبدیلش کنی ممکنه ارور Permission Denied رو دریافت کنی. مثل من ;D البته نمیدونم دلیلش چیه!
قاضی : تو السالوادور چه کار میکردی؟
چه‌گوارا : آفتاب میگرفتم
قاضی : پس چرا ساختمان دادگستری رو منفجر کردی؟
چه‌گوارا : جلوی آفتاب رو گرفته بود