FASM으로 컴파일 된 x86 ASM의 EXE 크기를 줄이는 방법은 무엇입니까?


14

연습으로, x86 Assembly Language 에서이 과제에 대한 간단한 솔루션을 만들었습니다 . Windows에서 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'

이것을 컴파일하면 예상보다 큰 실행 파일이 생성됩니다. 다음은 16 진수 덤프입니다.

https://pastebin.com/W5sUTvTe

코드 섹션과 데이터 및 라이브러리 가져 오기 섹션 사이에 빈 공간이 많고 코드에 "이 프로그램을 DOS 모드에서 실행할 수 없습니다"라는 메시지가 표시됩니다. 코드 골프에 적합한 작은 파일로 소스 코드를 어셈블하려면 어떻게해야합니까?

부수적으로, stdout가져 오기 msvcrt및 호출 하지 않고 인쇄하는 더 좋은 방법에 대한 제안을 printf환영합니다.


@iBug 죄송합니다. 물어볼 수있는 더 적합한 장소를 제안 해 주시겠습니까?
vasilescur

12
@iBug 팁 특정 상황에서 골프 도움을 요청하는 질문은 여기서 가장 분명한 주제가 아닙니다 .
AdmBorkBork


1
시작 : push char Lb : call [printf] call [printf] call [printf] call [printf] inc [char] cmp [char], 'Z'jle Lb 그렇지 않으면 스택을 소비 할 수 있기 때문에 ; printf에 대한 각 호출이 esp를 조정하는 명령을 추가
해야하는지 확인

1
대신 printf와, 당신은의 WriteFile (표준 출력), KERNEL32 이외의 수입이 필요 없습니다 (기본적으로 존재하는, 당신은 단지 주소를 확인해야 할) 수
피터 ferrie

답변:


2

꽤 일반적인 팁이지만

PE EXE 대신 COM 파일 형식을 사용하십시오.

PE EXE에는 코드 골프에서 형식을 거의 쓸모 없게 만드는 몇 가지 결함이 있습니다. 첫 번째는 이미지 정렬 (Windows는 EXE 파일이 올바르게 정렬되지 않으면 실행되지 않음)이고 두 번째는 헤더 크기입니다. 중요하지 않은 몇 가지 요소가 있습니다 (실행 파일을 섹션으로 나눔).

COM 파일 형식 (플랫 바이너리와 거의 동일)을 사용하면 다음과 같은 이점이 있습니다.

  • 헤더 코드 0, 파일이 섹션으로 나뉘 지 않음
  • 이미지 정렬 없음 (이미지 크기를 2의 거듭 제곱으로 나눌 수는 없지만 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으로 자유롭게 변환 할 수 있으며 완벽하게 작동합니다.


나는이 질문에 대한 답변과 구글에서 다시 갔다했습니다 믿을 수 없다
르지 Szewczyk
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.