"cat a.out"의 출력이 바이너리가 아닌 이상한 텍스트인 이유는 무엇입니까? [복사]

"cat a.out"의 출력이 바이너리가 아닌 이상한 텍스트인 이유는 무엇입니까? [복사]

"a.out"이 객체 코드(바이너리)를 나타내는 데 사용되는 파일 형식이고 어셈블러 출력의 짧은 형식이라는 것은 모두 알고 있으므로 cat a.out바이너리도 제공해야 하는데 왜 이런 일이 발생하지 않는 걸까요?

나는 출력이 순수한 바이너리일 것으로 기대합니다. 즉, 1과 0만 의미합니다.

답변1

컴파일된 코드는 (보통 상당히 긴) 바이트 시퀀스입니다. 이러한 파일을 사용하는 경우 cat터미널은 ASCII/UTF8/UTF16 내에서 동일한 바이트 값을 가진 문자를 표시하려고 시도합니다. 대부분의 바이트 조합에서는 실패하므로 결과는 cat a.out횡설수설처럼 보입니다.

16진수로 사용되는 바이너리 값 보기

$ od -x a.out
0000000      facf    feed    0007    0100    0003    8000    0002    0000
0000020      000f    0000    04b0    0000    0085    0020    0000    0000
0000040      0019    0000    0048    0000    5f5f    4150    4547    455a
0000060      4f52    0000    0000    0000    0000    0000    0000    0000
0000100      0000    0000    0001    0000    0000    0000    0000    0000
...

또는 시스템에 있는 경우

$ hexdump -C a.out
00000000  cf fa ed fe 07 00 00 01  03 00 00 80 02 00 00 00  |................|
00000010  0f 00 00 00 b0 04 00 00  85 00 20 00 00 00 00 00  |.......... .....|
00000020  19 00 00 00 48 00 00 00  5f 5f 50 41 47 45 5a 45  |....H...__PAGEZE|
00000030  52 4f 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |RO..............|
00000040  00 00 00 00 01 00 00 00  00 00 00 00 00 00 00 00  |................|
...
00000f90  00 00 00 41 53 ff 25 65  00 00 00 90 68 00 00 00  |...AS.%e....h...|
00000fa0  00 e9 e6 ff ff ff 48 65  6c 6c 6f 2c 20 57 6f 72  |......Hello, Wor|
00000fb0  6c 64 21 0a 00 00 00 00  01 00 00 00 1c 00 00 00  |ld!.............|
00000fc0  00 00 00 00 1c 00 00 00  00 00 00 00 1c 00 00 00  |................|
...

답변2

모든 파일은 일련의 숫자일 뿐입니다. 모든 파일은 정의한 대로 "순수 바이너리"입니다.

파일에 있는 숫자의 의미는 선택한 번역 방법에 따라 다릅니다.

예를 들어보겠습니다. helloworld.c 파일은 간단한 C 프로그램입니다.아니요실행 파일이지만 소스 코드 파일입니다.

od -t c프로그램은 "ASCII"라는 규칙을 사용하여 숫자를 "문자"로 변환합니다.

~ $ od -t c helloworld.c
0000000   #   i   n   c   l   u   d   e       <   s   t   d   i   o   .
0000020   h   >  \n  \n   i   n   t       m   a   i   n   (   i   n   t
0000040       a   r   g   c   ,       c   h   a   r       *   *   a   r
0000060   g   v   )       {  \n  \t   p   r   i   n   t   f   (   "   h
0000100   e   l   l   o       w   o   r   l   d   "   )   ;  \n   }  \n
0000120

od -t x1z프로그램은 파일의 숫자를 10진수와 문자(마지막 열)로 변환합니다.

~ $ od -t x1z  helloworld.c
0000000 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 69 6f 2e  >#include <stdio.<
0000020 68 3e 0a 0a 69 6e 74 20 6d 61 69 6e 28 69 6e 74  >h>..int main(int<
0000040 20 61 72 67 63 2c 20 63 68 61 72 20 2a 2a 61 72  > argc, char **ar<
0000060 67 76 29 20 7b 0a 09 70 72 69 6e 74 66 28 22 68  >gv) {..printf("h<
0000100 65 6c 6c 6f 20 77 6f 72 6c 64 22 29 3b 0a 7d 0a  >ello world");.}.<
0000120

xdd -b프로그램은 파일의 숫자를 이진수와 문자(마지막 열)로 변환합니다.

~ $ xxd -b helloworld.c
00000000: 00100011 01101001 01101110 01100011 01101100 01110101  #inclu
00000006: 01100100 01100101 00100000 00111100 01110011 01110100  de <st
0000000c: 01100100 01101001 01101111 00101110 01101000 00111110  dio.h>
00000012: 00001010 00001010 01101001 01101110 01110100 00100000  ..int
00000018: 01101101 01100001 01101001 01101110 00101000 01101001  main(i
0000001e: 01101110 01110100 00100000 01100001 01110010 01100111  nt arg
00000024: 01100011 00101100 00100000 01100011 01101000 01100001  c, cha
0000002a: 01110010 00100000 00101010 00101010 01100001 01110010  r **ar
00000030: 01100111 01110110 00101001 00100000 01111011 00001010  gv) {.
00000036: 00001001 01110000 01110010 01101001 01101110 01110100  .print
0000003c: 01100110 00101000 00100010 01101000 01100101 01101100  f("hel
00000042: 01101100 01101111 00100000 01110111 01101111 01110010  lo wor
00000048: 01101100 01100100 00100010 00101001 00111011 00001010  ld");.
0000004e: 01111101 00001010                                      }.

파일의 첫 번째 숫자는 35(10진수), 00100011(2진수) 또는 "#"(UTF-8)으로 표시될 수 있습니다. 번역 방법을 선택하는 방법에 따라 다릅니다.

관련 정보