คำตอบสั้น ๆ คือโครงสร้างภาษาส่วนใหญ่ที่รองรับโดย C ได้รับการสนับสนุนโดยไมโครโปรเซสเซอร์ของคอมพิวเตอร์เป้าหมายดังนั้นโค้ด C ที่คอมไพล์จึงแปลภาษาแอสเซมบลีของไมโครโปรเซสเซอร์ได้อย่างดีและมีประสิทธิภาพจึงส่งผลให้โค้ดมีขนาดเล็กลงและมีขนาดเล็กลง
คำตอบที่ยาวขึ้นต้องใช้ความรู้ภาษาแอสเซมบลีเล็กน้อย ใน C คำสั่งเช่นนี้:
int myInt = 10;
จะแปลเป็นสิ่งนี้ในการประกอบ:
myInt dw 1
mov myInt,10
เปรียบเทียบสิ่งนี้กับ C ++:
MyClass myClass;
myClass.set_myInt(10);
รหัสภาษาแอสเซมบลีที่ได้ (ขึ้นอยู่กับว่า MyClass () ใหญ่แค่ไหน) สามารถเพิ่มบรรทัดภาษาแอสเซมบลีได้มากถึงหลายร้อยบรรทัด
โดยไม่ต้องสร้างโปรแกรมในภาษาแอสเซมบลีจริง ๆ C ที่บริสุทธิ์น่าจะเป็นโค้ดที่ "เรียบเนียนที่สุด" และ "แน่นที่สุด" ที่คุณสามารถสร้างโปรแกรมได้
แก้ไข
จากความคิดเห็นเกี่ยวกับคำตอบของฉันฉันตัดสินใจที่จะทำการทดสอบเพื่อความมีสติของตัวเอง ฉันสร้างโปรแกรมชื่อ "test.c" ซึ่งมีลักษณะดังนี้:
#include <stdio.h>
void main()
{
int myInt=10;
printf("%d\n", myInt);
}
ฉันรวบรวมสิ่งนี้ลงในแอสเซมบลีโดยใช้ gcc ฉันใช้บรรทัดคำสั่งต่อไปนี้เพื่อรวบรวม:
gcc -S -O2 test.c
นี่คือภาษาแอสเซมบลีที่ได้:
.file "test.c"
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "%d\n"
.section .text.unlikely,"ax",@progbits
.LCOLDB1:
.section .text.startup,"ax",@progbits
.LHOTB1:
.p2align 4,,15
.globl main
.type main, @function
main:
.LFB24:
.cfi_startproc
movl $10, %edx
movl $.LC0, %esi
movl $1, %edi
xorl %eax, %eax
jmp __printf_chk
.cfi_endproc
.LFE24:
.size main, .-main
.section .text.unlikely
.LCOLDE1:
.section .text.startup
.LHOTE1:
.ident "GCC: (Ubuntu 4.9.1-16ubuntu6) 4.9.1"
.section .note.GNU-stack,"",@progbits
จากนั้นฉันสร้างไฟล์ชื่อ "test.cpp" ซึ่งกำหนดคลาสและเอาท์พุทแบบเดียวกันกับ "test.c":
#include <iostream>
using namespace std;
class MyClass {
int myVar;
public:
void set_myVar(int);
int get_myVar(void);
};
void MyClass::set_myVar(int val)
{
myVar = val;
}
int MyClass::get_myVar(void)
{
return myVar;
}
int main()
{
MyClass myClass;
myClass.set_myVar(10);
cout << myClass.get_myVar() << endl;
return 0;
}
ฉันรวบรวมมันในลักษณะเดียวกันโดยใช้คำสั่งนี้:
g++ -O2 -S test.cpp
นี่คือไฟล์ประกอบผลลัพธ์:
.file "test.cpp"
.section .text.unlikely,"ax",@progbits
.align 2
.LCOLDB0:
.text
.LHOTB0:
.align 2
.p2align 4,,15
.globl _ZN7MyClass9set_myVarEi
.type _ZN7MyClass9set_myVarEi, @function
_ZN7MyClass9set_myVarEi:
.LFB1047:
.cfi_startproc
movl %esi, (%rdi)
ret
.cfi_endproc
.LFE1047:
.size _ZN7MyClass9set_myVarEi, .-_ZN7MyClass9set_myVarEi
.section .text.unlikely
.LCOLDE0:
.text
.LHOTE0:
.section .text.unlikely
.align 2
.LCOLDB1:
.text
.LHOTB1:
.align 2
.p2align 4,,15
.globl _ZN7MyClass9get_myVarEv
.type _ZN7MyClass9get_myVarEv, @function
_ZN7MyClass9get_myVarEv:
.LFB1048:
.cfi_startproc
movl (%rdi), %eax
ret
.cfi_endproc
.LFE1048:
.size _ZN7MyClass9get_myVarEv, .-_ZN7MyClass9get_myVarEv
.section .text.unlikely
.LCOLDE1:
.text
.LHOTE1:
.section .text.unlikely
.LCOLDB2:
.section .text.startup,"ax",@progbits
.LHOTB2:
.p2align 4,,15
.globl main
.type main, @function
main:
.LFB1049:
.cfi_startproc
subq $8, %rsp
.cfi_def_cfa_offset 16
movl $10, %esi
movl $_ZSt4cout, %edi
call _ZNSolsEi
movq %rax, %rdi
call _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
xorl %eax, %eax
addq $8, %rsp
.cfi_def_cfa_offset 8
ret
.cfi_endproc
.LFE1049:
.size main, .-main
.section .text.unlikely
.LCOLDE2:
.section .text.startup
.LHOTE2:
.section .text.unlikely
.LCOLDB3:
.section .text.startup
.LHOTB3:
.p2align 4,,15
.type _GLOBAL__sub_I__ZN7MyClass9set_myVarEi, @function
_GLOBAL__sub_I__ZN7MyClass9set_myVarEi:
.LFB1056:
.cfi_startproc
subq $8, %rsp
.cfi_def_cfa_offset 16
movl $_ZStL8__ioinit, %edi
call _ZNSt8ios_base4InitC1Ev
movl $__dso_handle, %edx
movl $_ZStL8__ioinit, %esi
movl $_ZNSt8ios_base4InitD1Ev, %edi
addq $8, %rsp
.cfi_def_cfa_offset 8
jmp __cxa_atexit
.cfi_endproc
.LFE1056:
.size _GLOBAL__sub_I__ZN7MyClass9set_myVarEi, .-_GLOBAL__sub_I__ZN7MyClass9set_myVarEi
.section .text.unlikely
.LCOLDE3:
.section .text.startup
.LHOTE3:
.section .init_array,"aw"
.align 8
.quad _GLOBAL__sub_I__ZN7MyClass9set_myVarEi
.local _ZStL8__ioinit
.comm _ZStL8__ioinit,1,1
.hidden __dso_handle
.ident "GCC: (Ubuntu 4.9.1-16ubuntu6) 4.9.1"
.section .note.GNU-stack,"",@progbits
อย่างที่คุณเห็นได้อย่างชัดเจนไฟล์ประกอบที่ได้จะมีขนาดใหญ่กว่ามากในไฟล์ C ++ จากนั้นจึงอยู่ในไฟล์ C แม้ว่าคุณจะตัดสิ่งอื่น ๆ ออกไปทั้งหมดและเพียงแค่เปรียบเทียบ C "main" กับ "main" ของ C ++ แต่ก็มีสิ่งพิเศษมากมาย