Skip to content
KitploitKITPLOIT
उपकरणब्लॉग
जमा करें
उपकरणब्लॉग
जमा करें

हैकिंग, पेनटेस्ट और साइबर सुरक्षा उपकरण आपके सुरक्षा शस्त्रागार के लिए!

Kitploit हैकिंग, साइबर सुरक्षा और पेंटेस्टिंग टूल्स की एक निर्देशिका है। कमजोरियों को खोजने, सिस्टम का विश्लेषण करने, परीक्षण को स्वचालित करने और अपनी सुरक्षा को मजबूत करने के लिए नवीनतम प्रोजेक्ट अपडेट खोजें।

··फ़ीड·संपर्क·गोपनीयता·© 2026 Kitploit

टूल निर्देशिका

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
उपकरण/GitHubGitHub/mahmoudimus/static_asm
पेलोड जनरेशनकोड विश्लेषणशोषणरिवर्स इंजीनियरिंगशेलकोडबाइनरी विश्लेषणलर्निंग और शिक्षाशेलकोड जनरेशनलर्निंग पाथ और कोर्स
GitHubmahmoudimus/static_asm

static_asm

x86/x86-64 निर्देश एन्कोडिंग के लिए हेडर-ओनली C++2x कम्पाइल-टाइम असेंबलर

31167 महीने पहलेKitploit द्वारा समीक्षित

सबसे लोकप्रिय

सभी देखें →

हमारे समुदाय द्वारा सबसे अधिक उपयोग किए जाने वाले उपकरण खोजें।

सभी उपकरण खोजें

हमारे उपकरणों का संग्रह ब्राउज़ करें

सभी उपकरण देखें →
रिपॉजिटरी देखें
वेबसाइट
साझा करें

static_asm

CI License

एक हेडर-ओनली C++20 लाइब्रेरी जो संकलन-समय पर x86/x86-64 निर्देश एन्कोडिंग के लिए है।

यह प्रोजेक्ट बूस्ट सॉफ़्टवेयर लाइसेंस 1.0 और MIT लाइसेंस के तहत दोहरे-लाइसेंस है। आप कोई भी लाइसेंस चुन सकते हैं।

उद्देश्य

  • x86 असेंबली एन्कोडिंग को व्यावहारिक और मज़ेदार तरीके से सीखना
  • पूर्ण प्रकार सुरक्षा के साथ संकलन समय पर असेंबली निर्देश उत्पन्न करना
  • रनटाइम ओवरहेड के बिना शेलकोड और JIT कोड टेम्पलेट बनाना

त्वरित शुरुआत

root@kitploit:~
#include "static_asm.hpp"

using namespace static_asm::x86::registers;
using namespace static_asm::x86::instructions;

// संकलन समय पर मशीन कोड बनाएं
constexpr auto code = core::assemble(
    mov(rax, 0x12345678),    // mov rax, imm32
    add(rax, rcx),           // add rax, rcx
    xor_(r8, r8),            // xor r8, r8
    call(rax),               // call rax
    ret()                    // ret
);
// code एक std::array<uint8_t, N> है - पूरी तरह constexpr!

श्रेणी के अनुसार उदाहरण

ALU संचालन

root@kitploit:~
// रजिस्टर से रजिस्टर
add(rax, rbx);           // 48 01 D8
sub(ecx, edx);           // 29 D1
and_(r8, r9);            // 4D 21 C8
or_(rsi, rdi);           // 48 09 FE
xor_(eax, eax);          // 31 C0 (रजिस्टर को शून्य करने का सामान्य तरीका)
cmp(rax, rcx);           // 48 39 C8

// रजिस्टर के साथ तत्काल मान
add(rax, 0x10);          // 48 83 C0 10 (हस्ताक्षर-विस्तारित imm8)
add(rax, 0x10000);       // 48 05 00 00 01 00 (imm32)
sub(ecx, 100);           // 83 E9 64
and_(rdx, 0xFF);         // 48 83 E2 FF

// मेमोरी ऑपरेंड के साथ
add(eax, dword_ptr(rbx));              // 03 03
add(rax, qword_ptr(rcx + 0x10));       // 48 03 41 10
sub(dword_ptr(rsp + 0x20), eax);       // 29 44 24 20

डेटा मूवमेंट

root@kitploit:~
// रजिस्टर से रजिस्टर
mov(rax, rbx);           // 48 89 D8
mov(eax, ecx);           // 89 C8
mov(r8, r9);             // 4D 89 C8

// तत्काल मान से रजिस्टर
mov(rax, 0x12345678);    // 48 C7 C0 78 56 34 12
mov(eax, 0xDEADBEEF);    // B8 EF BE AD DE

// मेमोरी संचालन
mov(rax, qword_ptr(rbx));              // 48 8B 03
mov(eax, dword_ptr(rcx + 0x10));       // 8B 41 10
mov(qword_ptr(rsp + 0x8), rax);        // 48 89 44 24 08
mov(dword_ptr(rbp - 0x20), 0x100);     // C7 45 E0 00 01 00 00

// शून्य/हस्ताक्षर विस्तार
movzx(eax, bl);          // 0F B6 C3 (बाइट को dword में शून्य-विस्तार)
movzx(rax, bx);          // 48 0F B7 C3 (शब्द को qword में शून्य-विस्तार)
movsx(eax, cl);          // 0F BE C1 (बाइट को dword में हस्ताक्षर-विस्तार)
movsx(rax, dx);          // 48 0F BF C2 (शब्द को qword में हस्ताक्षर-विस्तार)
movsxd(rax, ecx);        // 48 63 C1 (dword को qword में हस्ताक्षर-विस्तार)

// प्रभावी पता लोड करें
lea(rax, qword_ptr(rbx + rcx * s4));           // 48 8D 04 8B
lea(rax, qword_ptr(rbx + rcx * s8 + 0x10));    // 48 8D 44 CB 10

// आदान-प्रदान
xchg(rax, rbx);          // 48 87 D8

SIB एड्रेसिंग (स्केल-इंडेक्स-बेस)

root@kitploit:~
// [base + index*scale]
mov(eax, dword_ptr(rbx + rcx * s1));   // 8B 04 0B
mov(eax, dword_ptr(rbx + rcx * s2));   // 8B 04 4B
mov(eax, dword_ptr(rbx + rcx * s4));   // 8B 04 8B
mov(eax, dword_ptr(rbx + rcx * s8));   // 8B 04 CB

// [base + index*scale + displacement]
mov(rax, qword_ptr(rbx + rcx * s4 + 0x10));     // 48 8B 44 8B 10
mov(rax, qword_ptr(r12 + r13 * s8 + 0x1000));   // 4B 8B 84 EC 00 10 00 00

// SIB पते पर स्टोर करें
mov(dword_ptr(rax + rdx * s4), ecx);            // 89 0C 90
mov(qword_ptr(rbx + rsi * s8 + 0x20), rax);     // 48 89 44 F3 20

// SIB के साथ LEA (पता गणना के लिए उपयोगी)
lea(rax, qword_ptr(rbx + rcx * s4));            // 48 8D 04 8B
lea(rax, qword_ptr(rdi + rsi * s8 + 0x100));    // 48 8D 84 F7 00 01 00 00

शिफ्ट और रोटेट

root@kitploit:~
// 1 से शिफ्ट
shl(eax, 1);             // D1 E0
shr(rax, 1);             // 48 D1 E8
sar(ecx, 1);             // D1 F9

// तत्काल मान से शिफ्ट
shl(eax, 4);             // C1 E0 04
shr(rax, 8);             // 48 C1 E8 08
sar(rdx, 16);            // 48 C1 FA 10

// CL रजिस्टर से शिफ्ट
shl(eax, cl);            // D3 E0
shr(rax, cl);            // 48 D3 E8

// रोटेट
rol(eax, 1);             // D1 C0
ror(rax, 8);             // 48 C1 C8 08
rcl(ecx, cl);            // D3 D1
rcr(rdx, 1);             // 48 D1 DA

गुणा और भाग

root@kitploit:~
// एकल ऑपरेंड (परिणाम rdx:rax में)
mul(rbx);                // 48 F7 E3 (अहस्ताक्षरित: rdx:rax = rax * rbx)
imul(rcx);               // 48 F7 E9 (हस्ताक्षरित: rdx:rax = rax * rcx)
div(rbx);                // 48 F7 F3 (अहस्ताक्षरित: rax = rdx:rax / rbx, rdx = शेष)
idiv(rcx);               // 48 F7 F9 (हस्ताक्षरित विभाजन)

// दो-ऑपरेंड IMUL (dest = dest * src)
imul(rax, rbx);          // 48 0F AF C3
imul(ecx, edx);          // 0F AF CA

// तीन-ऑपरेंड IMUL (dest = src * imm)
imul(rax, rbx, 10);      // 48 6B C3 0A
imul(ecx, edx, 1000);    // 69 CA E8 03 00 00

नियंत्रण प्रवाह

root@kitploit:~
// बिना शर्त कूद
jmp(0x10);               // EB 10 (छोटा, 8-बिट ऑफ़सेट)
jmp(0x1000);             // E9 00 10 00 00 (निकट, 32-बिट ऑफ़सेट)
jmp(rax);                // FF E0 (अप्रत्यक्ष)
jmp(here);               // EB FE (jmp $, अनंत लूप)

// सशर्त कूद (8-बिट ऑफ़सेट)
jz(0x10);                // 74 10
jnz(0x20);               // 75 20
jb(0x08);                // 72 08 (नीचे/कैरी)
jae(0x08);               // 73 08 (ऊपर या बराबर/कोई कैरी नहीं)
jl(0x10);                // 7C 10 (कम से, हस्ताक्षरित)
jge(0x10);               // 7D 10 (अधिक या बराबर, हस्ताक्षरित)

// सशर्त कूद (लंबी शाखाओं के लिए 32-बिट ऑफ़सेट)
jz_near(0x10000);        // 0F 84 00 00 01 00
jnz_near(0x20000);       // 0F 85 00 00 02 00

// कॉल और रिटर्न
call(rax);               // FF D0 (अप्रत्यक्ष कॉल)
call(0x100);             // E8 00 01 00 00 (सापेक्ष कॉल)
ret();                   // C3
ret(0x10);               // C2 10 00 (वापसी और 16 बाइट पॉप)

सशर्त मूव

root@kitploit:~
// शर्त सत्य होने पर मूव करें (कोई शाखा दंड नहीं!)
cmovz(rax, rbx);         // 48 0F 44 C3 (शून्य होने पर मूव)
cmovnz(eax, ecx);        // 0F 45 C1 (शून्य न होने पर मूव)
cmovl(rax, rdx);         // 48 0F 4C C2 (कम होने पर मूव, हस्ताक्षरित)
cmovge(ecx, esi);        // 0F 4D CE (अधिक या बराबर होने पर मूव, हस्ताक्षरित)
cmovb(rax, rbx);         // 48 0F 42 C3 (नीचे होने पर मूव, अहस्ताक्षरित)
cmovae(edx, edi);        // 0F 43 D7 (ऊपर या बराबर होने पर मूव, अहस्ताक्षरित)

// मेमोरी स्रोत के साथ
cmovz(rax, qword_ptr(rbx));           // 48 0F 44 03
cmovnz(eax, dword_ptr(rcx + 0x10));   // 0F 45 41 10

बिट संचालन

root@kitploit:~
// बिट परीक्षण
bt(eax, 5);              // 0F BA E0 05
bt(rax, rbx);            // 48 0F A3 D8

// बिट परीक्षण और सेट/रीसेट/पूरक
bts(eax, 10);            // 0F BA E8 0A (परीक्षण और सेट)
btr(rax, rcx);           // 48 0F B3 C8 (परीक्षण और रीसेट)
btc(edx, 3);             // 0F BA FA 03 (परीक्षण और पूरक)

// बिट स्कैन
bsf(eax, ecx);           // 0F BC C1 (पहले 1 के लिए आगे स्कैन)
bsr(rax, rbx);           // 48 0F BD C3 (पहले 1 के लिए पीछे स्कैन)

// जनसंख्या गणना और अग्रणी/अनुगामी शून्य
popcnt(eax, ecx);        // F3 0F B8 C1
lzcnt(rax, rbx);         // F3 48 0F BD C3
tzcnt(eax, edx);         // F3 0F BC C2

// बाइट स्वैप
bswap(eax);              // 0F C8 (बाइट क्रम उलटें)
bswap(rax);              // 48 0F C8

स्ट्रिंग संचालन

root@kitploit:~
// मूल स्ट्रिंग ऑप्स ([rsi] और/या [rdi] पर काम करते हैं)
movsb();                 // A4 (बाइट [rsi] -> [rdi] ले जाएं)
movsw();                 // 66 A5
movsd();                 // A5
movsq();                 // 48 A5

cmpsb();                 // A6 ([rsi] की [rdi] से तुलना करें)
stosb();                 // AA (al को [rdi] में स्टोर करें)
lodsb();                 // AC ([rsi] को al में लोड करें)
scasb();                 // AE (al की [rdi] से तुलना करें)

// REP उपसर्ग के साथ (rcx बार दोहराएं)
rep_movsb();             // F3 A4 (memcpy)
rep_movsq();             // F3 48 A5 (तेज़ memcpy, एक बार में 8 बाइट)
rep_stosb();             // F3 AA (memset)
rep_stosq();             // F3 48 AB

// REPE/REPNE के साथ (बराबर होने/न होने तक दोहराएं)
repe_cmpsb();            // F3 A6 (बेमेल होने तक स्ट्रिंग की तुलना)
repne_scasb();           // F2 AE (स्ट्रिंग में बाइट खोजें)

स्टैक संचालन

root@kitploit:~
push(rax);               // 50
push(rbx);               // 53
push(r8);                // 41 50
push(0x10);              // 6A 10 (push imm8)
push(0x1000);            // 68 00 10 00 00 (push imm32)

pop(rax);                // 58
pop(rbx);                // 5B
pop(r15);                // 41 5F

सिस्टम निर्देश

root@kitploit:~
// सिस्टम कॉल
syscall_();              // 0F 05 (64-बिट syscall)
sysenter();              // 0F 34
sysexit();               // 0F 35

// इंटरप्ट
int3();                  // CC (ब्रेकपॉइंट)
int_(0x80);              // CD 80 (Linux 32-बिट syscall)
int_(0x21);              // CD 21 (DOS इंटरप्ट)

// CPU जानकारी
cpuid();                 // 0F A2
rdtsc();                 // 0F 31
rdtscp();                // 0F 01 F9

// विशेषाधिकार
cli();                   // FA (इंटरप्ट साफ़ करें)
sti();                   // FB (इंटरप्ट सेट करें)
hlt();                   // F4 (रुकें)

// इंटरप्ट रिटर्न
iret();                  // CF (16-बिट)
iretd();                 // CF (32-बिट)
iretq();                 // 48 CF (64-बिट)

अनेक निर्देशों को असेंबल करना

निर्देश बाइट सरणियों को संयोजित करने के लिए core::assemble() का उपयोग करें:

root@kitploit:~
constexpr auto prologue = core::assemble(
    push(rbp),
    mov(rbp, rsp),
    sub(rsp, 0x20)
);

constexpr auto epilogue = core::assemble(
    add(rsp, 0x20),
    pop(rbp),
    ret()
);

// इन्हें मिलाएं
constexpr auto full_function = core::assemble(prologue, epilogue);

स्थापना

विकल्प 1: CMake FetchContent (अनुशंसित)

अपने CMakeLists.txt में जोड़ें:

root@kitploit:~
include(FetchContent)
FetchContent_Declare(
    static_asm
    GIT_REPOSITORY https://github.com/mahmoudimus/static_asm.git
    GIT_TAG v1.0.0  # या विशिष्ट कमिट
)
FetchContent_MakeAvailable(static_asm)

target_link_libraries(your_target PRIVATE static_asm::static_asm)

विकल्प 2: CMake add_subdirectory

क्लोन करें या git सबमॉड्यूल के रूप में जोड़ें:

root@kitploit:~
git submodule add https://github.com/mahmoudimus/static_asm.git external/static_asm

फिर अपने CMakeLists.txt में:

root@kitploit:~
add_subdirectory(external/static_asm)
target_link_libraries(your_target PRIVATE static_asm::static_asm)

जब add_subdirectory या FetchContent के माध्यम से शामिल किया जाता है, तो केवल static_asm::static_asm इंटरफ़ेस लाइब्रेरी लक्ष्य आपके प्रोजेक्ट में जोड़ा जाता है। परीक्षण और उदाहरण तब तक नहीं बनाए जाते जब तक -DSTATIC_ASM_BUILD_TESTS=ON के साथ स्पष्ट रूप से सक्षम न किया जाए।

विकल्प 3: एकल हेडर

रिलीज़ पेज से static_asm.hpp डाउनलोड करें और इसे सीधे शामिल करें:

root@kitploit:~
#include "static_asm.hpp"

विकल्प 4: सिस्टम स्थापना

root@kitploit:~
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --install build --prefix /usr/local

फिर find_package का उपयोग करें:

root@kitploit:~
find_package(static_asm REQUIRED)
target_link_libraries(your_target PRIVATE static_asm::static_asm)

निर्माण

root@kitploit:~
# कॉन्फ़िगर करें
cmake -B build -DCMAKE_BUILD_TYPE=Release

# निर्माण
cmake --build build

# परीक्षण चलाएं
ctest --test-dir build --output-on-failure

# उदाहरणों के साथ निर्माण (केवल Clang, इनलाइन असेंबली का उपयोग करता है)
cmake -B build -DCMAKE_BUILD_TYPE=Release -DSTATIC_ASM_BUILD_EXAMPLES=ON

प्लेटफ़ॉर्म समर्थन:

  • Linux (GCC 11+, Clang 14+)
  • macOS (Apple Clang, Clang)
  • Windows (MSVC 2022+)

नोट: core::emit() इनलाइन असेंबली सुविधा के लिए -O2 अनुकूलन के साथ Clang की आवश्यकता है।

समर्थित निर्देश

श्रेणीनिर्देश
ALUADD, ADC, SUB, SBB, AND, OR, XOR, CMP, TEST
यूनरीINC, DEC, NEG, NOT
गुणा/भागMUL, IMUL (1/2/3 ऑपरेंड रूप), DIV, IDIV
डेटा मूवमेंटMOV, MOVABS, MOVZX, MOVSX, MOVSXD, LEA, XCHG, PUSH, POP
शिफ्ट/रोटेटSHL, SHR, SAL, SAR, ROL, ROR, RCL, RCR
नियंत्रण प्रवाहJMP, CALL, RET, RETF
सशर्त कूदJZ/JE, JNZ/JNE, JB/JC, JNB/JNC, JBE/JNA, JNBE/JA, JL, JNL, JLE, JNLE, JO, JNO, JS, JNS, JP, JNP (8-बिट और 32-बिट ऑफ़सेट)
सशर्त मूवCMOVA, CMOVAE, CMOVB, CMOVBE, CMOVE, CMOVG, CMOVGE, CMOVL, CMOVLE, CMOVNE, CMOVNO, CMOVNP, CMOVNS, CMOVO, CMOVP, CMOVS
बिट संचालनBT, BTC, BTR, BTS
बिट स्कैन/गणनाBSF, BSR, POPCNT, LZCNT, TZCNT, BSWAP
स्ट्रिंग संचालनMOVSB/W/D/Q, CMPSB/W/D/Q, LODSB/W/D/Q, STOSB/W/D/Q, SCASB/W/D/Q (REP/REPE/REPNE उपसर्गों के साथ)
सिस्टमSYSCALL, SYSENTER, SYSEXIT, INT, INT3, IRET/D/Q, CLI, STI, HLT, CPUID, RDTSC, RDTSCP
विविधNOP, UD2

ऑपरेंड समर्थन:

  • सभी 8/16/32/64-बिट सामान्य प्रयोजन रजिस्टर (AL-R15)
  • विस्तारित रजिस्टर (R8-R15, R8D-R15D, R8W-R15W, R8B-R15B)
  • तत्काल मान (8/16/32/64-बिट)
  • आधार रजिस्टर और विस्थापन के साथ मेमोरी ऑपरेंड
  • SIB एड्रेसिंग: [base + index*scale + disp] स्केल कारक 1, 2, 4, 8 के साथ

नोट: अभी तक कोई SIMD/AVX एक्सटेंशन नहीं।

विकास

वातावरण सेटअप

यह प्रोजेक्ट Python टूलिंग (कोड जनरेशन, सिंगल-हेडर अमलगमेशन) के लिए uv का उपयोग करता है।

root@kitploit:~
# uv स्थापित करें (यदि पहले से स्थापित नहीं है)
curl -LsSf https://astral.sh/uv/install.sh | sh

# स्थापना सत्यापित करें
uv --version

# सभी Python स्क्रिप्ट को uv के साथ सीधे चलाया जा सकता है (निर्भरताएं स्वचालित रूप से प्रबंधित होती हैं)
uv run scripts/gen_from_x86ref.py --help
uv run scripts/amalgamate.sh

आवश्यक उपकरण:

उपकरणउद्देश्यस्थापना
uvPython पैकेज/प्रोजेक्ट प्रबंधकcurl -LsSf https://astral.sh/uv/install.sh | sh
quomसिंगल-हेडर अमलगमेशनuv tool install quom
CMake 3.19+निर्माण प्रणालीcmake.org
C++20 कंपाइलरGCC 11+, Clang 14+, MSVC 2022+-

विकास के लिए वैकल्पिक उपकरण:

उपकरणउद्देश्यस्थापना
clang-formatकोड फ़ॉर्मेटिंगLLVM या सिस्टम पैकेज के माध्यम से
clang-tidyस्थैतिक विश्लेषणLLVM या सिस्टम पैकेज के माध्यम से

नए निर्देश जोड़ना

विकल्प 1: कोड जनरेटर का उपयोग करें

प्रोजेक्ट में एक जनरेटर शामिल है जो x86reference XML डेटाबेस को पार्स करता है:

root@kitploit:~
# निर्देश डेटाबेस सारांश दिखाएं
uv run scripts/gen_from_x86ref.py

# किसी विशिष्ट निर्देश का विवरण दिखाएं
uv run scripts/gen_from_x86ref.py -i lea
uv run scripts/gen_from_x86ref.py -i imul

# निर्देश डेटाबेस फ़ाइलें उत्पन्न करें
uv run scripts/gen_from_x86ref.py --generate-db

# विस्तृत परीक्षण फ़ाइल उत्पन्न करें
uv run scripts/gen_from_x86ref.py --generate-tests

विकल्प 2: मैन्युअल जोड़

  1. निर्देश db फ़ाइल (instdb, prefix_db, prefix_0fdb सरणियाँ) में जोड़ें
  2. encoder.hpp में एन्कोडर को कोड करें या मौजूदा एन्कोडर का विस्तार करें
  3. परीक्षण जोड़ें

सिंगल-हेडर लाइब्रेरी बनाने की तकनीकें

कोई भी स्वचालित उपकरण किसी मनमानी मल्टी-फ़ाइल C++ लाइब्रेरी को बिना कुछ मैन्युअल तैयारी के विश्वसनीय रूप से स्वच्छ, हेडर-ओनली संस्करण में परिवर्तित नहीं कर सकता है। निम्नलिखित तकनीकें यह सुनिश्चित करने में मदद करती हैं कि आपकी लाइब्रेरी को एक एकल हेडर फ़ाइल में सफलतापूर्वक समामेलित किया जा सकता है, जबकि यह सही, बनाए रखने योग्य और मानक-अनुपालन बनी रहे।

नोट: यह प्रोजेक्ट समामेलन के लिए quom और इन नियमों के प्रवर्तन को स्वचालित करने के लिए google-build-using-namespace चेक के साथ clang-tidy का उपयोग करता है। quom अपनी प्रसंस्करण क्षमताओं के माध्यम से तकनीक #4 (इनलाइन मार्कर) को भी आंशिक रूप से संभालता है।

1. स्रोत फ़ाइलों में using namespace से बचें

.cpp फ़ाइलों में फ़ाइल स्कोप पर using namespace खतरनाक है जब वे फ़ाइलें बाद में एक हेडर में शामिल की जाती हैं — यह आपके हेडर को शामिल करने वाले प्रत्येक अनुवाद इकाई के लिए वैश्विक नामस्थान को प्रदूषित करता है।

इसके बजाय अनुशंसित पैटर्न:

root@kitploit:~
// पसंदीदा: कार्यान्वयन को नामस्थान में लपेटें
namespace MyLib {
    Foo::Foo() {
        // ...
    }
}

या

root@kitploit:~
// स्पष्ट योग्यता (अधिक वर्बोज़ लेकिन बहुत स्पष्ट)
MyLib::Foo::Foo() {
    // ...
}

2. आंतरिक / निजी एपीआई को एक नेस्टेड नामस्थान में रखें

सार्वजनिक एपीआई मुख्य नामस्थान में होनी चाहिए। वह सब कुछ जो अंत-उपयोगकर्ताओं के लिए नहीं है, उसे detail या impl जैसे नेस्टेड नामस्थान में छिपाया जाना चाहिए।

सामान्य परिपाटी:

root@kitploit:~
namespace MyLib {
    namespace detail {           // बहुत व्यापक रूप से उपयोग किया जाता है
        // आंतरिक वर्ग, फ़ंक्शन, आदि।
    }
}

या

root@kitploit:~
namespace MyLib::impl {          // छोटा, सामान्य भी
    // आंतरिक कार्यान्वयन विवरण
}

C++17 और बाद के संस्करण इनलाइन नेस्टेड नामस्थान परिभाषाओं का समर्थन करते हैं, जो अधिक स्वच्छ हैं:

root@kitploit:~
namespace MyLib::detail {
    class InternalHelper { /* ... */ };
}

3. फ़ाइल-स्कोप स्थैतिक डेटा को static inline वर्ग सदस्यों में बदलें

.cpp फ़ाइलों में परिभाषित फ़ाइल-स्कोप static चर हेडर-ओनली दुनिया में समस्याग्रस्त हो जाते हैं (एकाधिक परिभाषाएं, ODR उल्लंघन)।

आधुनिक (C++17+) समाधान:

root@kitploit:~
// पहले (.cpp में)
namespace MyLib {
    static int s_counter = 0;

    int next_id() {
        return ++s_counter;
    }
}
root@kitploit:~
// बाद में (हेडर के लिए सुरक्षित)
namespace MyLib::detail {
    struct Globals {
        static inline int counter = 0;
    };
}

inline int MyLib::next_id() {
    return ++detail::Globals::counter;
}

static inline चर की गारंटी है कि कई बार शामिल होने पर भी एक ही परिभाषा होगी।

4. वर्ग निकायों के बाहर परिभाषित फ़ंक्शनों को inline के रूप में चिह्नित करें

कोई भी फ़ंक्शन, सदस्य फ़ंक्शन, कंस्ट्रक्टर, या डिस्ट्रक्टर जिसका बॉडी हेडर में दिखाई देता है (लेकिन वर्ग परिभाषा के अंदर नहीं) अवश्य ही inline के रूप में चिह्नित किया जाना चाहिए ताकि One Definition Rule (ODR) उल्लंघनों से बचा जा सके।

क्योंकि कई समामेलन स्क्रिप्ट विशुद्ध रूप से पाठ्य होती हैं और C++ शब्दार्थ को पार्स नहीं करती हैं, विकास के दौरान एक प्लेसहोल्डर मैक्रो (जैसे inline_t) का उपयोग करना एक सामान्य परिपाटी है:

root@kitploit:~
// MyLib.h (या सामान्य हेडर)
#define inline_t   /* सामान्य निर्माण के दौरान खाली */

// MyLib.cpp (विकास के दौरान)
namespace MyLib::detail {
    inline_t void Helper::do_work() {
        // कार्यान्वयन
    }
}

समामेलन के दौरान, उपकरण inline_t को inline से बदल देता है:

root@kitploit:~
// समामेलन / परिवर्तन के बाद
inline void MyLib::detail::Helper::do_work() {
    // ...
}

आप कोई भी मैक्रो नाम चुन सकते हैं (जैसे MYLIB_INLINE, INLINE_IMP, आदि) और अपनी समामेलन स्क्रिप्ट को तदनुसार कॉन्फ़िगर करें।

नोट: quom जैसे उपकरण C++ शामिल करने के शब्दार्थ को समझकर और समामेलन के दौरान फ़ंक्शन परिभाषाओं को ठीक से संभालकर इसे आंशिक रूप से स्वचालित कर सकते हैं, जिससे कई मामलों में मैन्युअल inline मार्करों की आवश्यकता कम हो जाती है।

सारांश — चार प्रमुख नियम

  1. कार्यान्वयन फ़ाइलों में नामस्थान/फ़ाइल स्कोप पर कभी भी using namespace … न लिखें।
  2. सभी आंतरिक/गैर-सार्वजनिक प्रतीकों को एक नेस्टेड नामस्थान (detail / impl) में रखें।
  3. फ़ाइल-स्कोप static डेटा को एक संरचना/वर्ग के static inline सदस्यों से बदलें।
  4. आउट-ऑफ-लाइन फ़ंक्शन निकायों को एक inline मार्कर मैक्रो (समामेलन के दौरान प्रतिस्थापित) के साथ चिह्नित करें।

इन चार प्रथाओं का पालन करने से एकल-हेडर वितरण में संक्रमण अधिक सुचारू और बहुत कम त्रुटि-प्रवण हो जाता है — भले ही विशुद्ध रूप से पाठ-आधारित समामेलन उपकरणों का उपयोग किया जा रहा हो।

श्रेय

  • प्रोटोटाइप के लिए Godbolt
  • Intel x86-64 मैनुअल
  • आउटपुट सत्यापित करने के लिए Defuse.ca
  • Geek ABC संदर्भ
  • निर्देश डेटाबेस XML के लिए mazegen/x86reference

आभार

यह प्रोजेक्ट Midi12 द्वारा cx_assembler पर आधारित है। मूल लाइब्रेरी ने C++ में संकलन-समय x86 असेंबली एन्कोडिंग के लिए आधार प्रदान किया।

टूल डाउनलोड करें