F86 के साथ संकलित x86 ASM का EXE आकार कैसे कम करें?


14

एक अभ्यास के रूप में, मैंने इस चुनौती के लिए, x86 विधानसभा भाषा में एक सरल समाधान बनाया है । मैं इसे विंडोज पर FASM के साथ चला रहा हूं। यहाँ मेरा स्रोत कोड है:

format PE console
entry start

include 'WIN32A.inc'

section '.text' code executable
start:
    push    char            ; Start at 'A'
    call    [printf]        ; Print the current letter 4 times
    call    [printf]
    call    [printf]
    call    [printf]
    inc     [char]          ; Increment the letter
    cmp     [char], 'Z'     ; Compare to 'Z'
    jle     start           ; char <= 'Z' --> goto start

section 'r.data' data readable writeable
    char    db  'A', 10, 0  ; Stores the current letter

section '.idata' data readable import
    library  msvcrt,   'msvcrt.dll'
    import   msvcrt, printf, 'printf'

जब मैं इसे संकलित करता हूं, मुझे उम्मीद से अधिक एक निष्पादन योग्य मिलता है। यहाँ एक हेक्सडम्प है:

https://pastebin.com/W5sUTvTe

मुझे लगता है कि कोड अनुभाग और डेटा और लाइब्रेरी आयात अनुभागों के बीच बहुत सी खाली जगह है, साथ ही एक संदेश "कोड में एम्बेडेड इस प्रोग्राम को डॉस मोड में नहीं चलाया जा सकता है"। मैं अपने स्रोत कोड को एक छोटी फ़ाइल में कैसे इकट्ठा कर सकता हूं, जो कोड गोल्फ के लिए उपयुक्त है?

एक साइड नोट के रूप में, stdoutआयात msvcrtऔर कॉलिंग के बिना प्रिंट करने के बेहतर तरीकों के सुझावों printfका स्वागत है।


@iBug मुझे यह सुनकर दुख हुआ। क्या आप कृपया मेरे पूछने के लिए अधिक उपयुक्त स्थान सुझा सकते हैं?
vasilescur

12
विशिष्ट मामलों में मदद गोल्फ के लिए पूछ @iBug टिप्स सवाल सबसे निश्चित रूप से कर रहे हैं नहीं विषय से हटकर यहां।
AdmBorkBork


1
यह होना चाहिए: स्टार्ट: पुश चार एलबी: कॉल [प्रिंटफ] कॉल [प्रिंटफ] कॉल [प्रिंटफ] कॉल [प्रिंटफ] इंक [चार] सीपीएम [चार], 'जेड ’एलएलबी क्योंकि यदि नहीं, तो स्टैक का उपभोग नहीं किया जा सकता है। ; एक को देखना है कि क्या प्रत्येक कॉल को
प्रिंट

1
प्रिंटफ के बजाय, आप कर सकते हैं WriteFile (stdout),
कर्नेल

जवाबों:


2

थोड़ा सामान्य टिप, लेकिन

PE EXE के बजाय COM फ़ाइल स्वरूप का उपयोग करें।

PE EXE में कुछ दोष हैं जो कोड-गोल्फ में प्रारूप को बहुत बेकार बनाते हैं। पहले एक छवि संरेखित है (यदि यह ठीक से संरेखित नहीं है तो विंडोज़ EXE फ़ाइल नहीं चलाएगा), और दूसरा शीर्षलेख आकार है। कुछ कारक हैं जो इस महत्वपूर्ण (वर्गों में निष्पादन योग्य को विभाजित करना) नहीं हैं।

COM फ़ाइल स्वरूप का उपयोग करने के लाभ (जो कि फ्लैट बाइनरी के बराबर है):

  • शून्य शीर्षलेख कोड, फ़ाइल को खंडों में विभाजित नहीं किया गया है
  • कोई छवि संरेखित नहीं करना (इसलिए छवि आकार दो की सख्ती से परिभाषित शक्ति से विभाज्य नहीं हो सकता है, लेकिन इसे 65K से अधिक होना चाहिए। यह बहुत अधिक परिवर्तन नहीं करता है, क्योंकि यदि आपका प्रस्तुतिकरण 65K से बड़ा है, तो आप कर रहे हैं। कुछ गलत)।
  • आप बाहरी पुस्तकालयों का उपयोग नहीं कर सकते हैं - यह वास्तव में एक प्लस है, क्योंकि आपको संदेह के बिना I / O प्रदर्शन करने का अन्य तरीका है। यही कारण है कि जहां है BIOS बीच में आता है काम आते हैं।
  • आपके पास सिस्टम से जुड़ी मेमोरी और डिवाइस पर सीधा नियंत्रण है, इसलिए कोई भी पेजिंग नहीं है, कोई एक्सेस उल्लंघन नहीं है, कोई मेमोरी प्रोटेक्शन नहीं है, कोई कंसीडर नहीं है, इसलिए और आगे। ये विशेषताएं वास्तव में रचनात्मक कार्यक्रमों को गोल्फ के लिए आसान बनाती हैं।

मैंने फ्लैट बाइनरी के रूप में काम करने के लिए आपके कोड को संशोधित किया है। यह आसान है:

ORG 100H

MOV DX, P
MOV AH, 9

L:
    INT 21H
    INT 21H
    INT 21H
    INT 21H

    INC BYTE [P]
    CMP BYTE [P], 'Z'
    JLE L

MOV AX, 4C00h
INT 21h

P DB "A", 10, "$"

आउटपुट बाइनरी सिर्फ 32 बाइट्स बड़ा है। मेरा मानना ​​है कि आकार को और भी कम करना संभव है, लेकिन यह सिर्फ एक शुरुआती बिंदु है।

के साथ इकट्ठा nasm -fbin file.asm -o file.com। ध्यान दें, यह उदाहरण NASM के लिए बनाया गया है, लेकिन आप इसे FASM में स्वतंत्र रूप से अनुवाद कर सकते हैं, और यह त्रुटिपूर्ण रूप से काम करेगा।


मुझे विश्वास नहीं हो रहा है कि मैंने इस सवाल का जवाब दिया है और इसे Google से वापस ले आया है
Krzysztof Szewczyk
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.