어셈블리어 질문좀 드릴게요..

thekero의 이미지

MS-DOS 매크로 어셈블러 (황희융 저, 1991년)로 공부 처음 시작하는데..

예제 따라하다가 똑같이 안나와서 질문 드려요..

프로그램은 EMU8086이라는 걸로 따라하고 있습니다.

MAIN   SEGMENT
       ASSUME CS:MAIN,DS:MAIN
;
       MOV    AX,CS
       MOV    DS,AX
       MOV    DL,XXX
       MOV    AH,2
       INT    21H
       MOV    CX,YYY
       MOV    DL,CH
       MOV    AH,2
       INT    21H
       MOV    DL,CL
       MOV    AH,2
       INT    21H
;
       MOV    AH,4CH
       INT    21H
;
XXX    DB     'X'
YYY    DW     3456H
;
MAIN   ENDS
       END
 
이렇게 예제를 입력하면 책이랑 똑같이 X4V 라는 값이 나오는데
 
MAIN   SEGMENT
       ASSUME CS:MAIN,DS:DATA
;
       MOV    AX,DATA
       MOV    DS,AX
       MOV    BX,AAA
       MOV    DL,BH
       MOV    AH,2
       INT    21H
       MOV    DL,BL
       MOV    AH,2
       INT    21H
;
       MOV    AH,4CH
       INT    21H
MAIN   ENDS
;
DATA   SEGMENT
AAA    DW     'AB'
DATA   ENDS
       END

이렇게 예제를 입력하면 값이 AB가 나와야 되는데 안 나옵니다.

두개 예제 차이는 하나의 세그먼트를 두느냐 여러개의 세그먼트를 두느냐 차이라고 책에 나와 있습니다.

무엇에 문제인가요..?

Necromancer의 이미지

실행파일 만들때 com으로 만드셨나요? com으로 만든거라면 실행전 os에서 로드할때 relocation을 안해서 세그먼트가 정확하게 안들어갑니다.

exe로 만드셨는데도 안된다면 주소 직접 넣어보세요.

mov bx,[aaa]

식으로.

Written By the Black Knight of Destruction

thekero의 이미지

emu8086에 보면 에뮬레이트라는 버튼이 있습니다. 그걸 눌러서 런을 눌렀는데 안 되더라구요..

지금 [] <= 직접주소지정방식 맞죠.? 이걸로 해봤는데도 안되네요..

실행환경은 윈도우7 64비트 입니다.

Necromancer의 이미지

에뮬레이터 안의 도스에서 asm -> obj -> exe 변환해서 실행한건가요 아니면 에뮬레이터로 그냥 실행한건가요? 에뮬레이터 바로 실행한거라면 relocation 문제로 보이네요.

relocation은 도스일경우는 EXE만 됩니다. COM은 relocation 없고 세그먼트를 알아서 써야 하는 수준. 코드상에는 세그먼트를 선언해놓고 그안에 코드와 데이터 넣어놨지만 이게 실제 로드되어서 실행되면 선언한 세그먼트의 위치는 시스템 환경에 따라 어디로 갈지 모릅니다. 그래서 실행할때마다 세그먼트의 실제 값을 프로그램이 실행되는 환경에 맞춰 변경하는 작업이 필요한데 이게 relocation 입니다.

Written By the Black Knight of Destruction

thekero의 이미지

아직 완전 초보 단계라서 말씀하신 relocation이 뭔지도 모르겠습니다 ㅜㅜ

다만 밑에서 설명해서 확인해보니 asm code를 bin으로 compile해서 emulate하는 방식인거 같습니다..

제가 써놓고도 뭔 소린지 모르겠네요

에구.. 어셈블리어 가르쳐주는 학원도 없구 해서 책 하나 잡구 하는데..

내용은 둘째치고.. 이렇게 물어볼수 있는곳이 거의 없어서..

저에게는 여기가 사막의 오아시스 같습니다 ^^

 의 이미지

MAIN   SEGMENT
       ASSUME CS:MAIN,DS:DATA
;
ENTRY:
       MOV    AX,DATA
       MOV    DS,AX
       MOV    BX,AAA
       MOV    DL,BH
       MOV    AH,2
       INT    21H
       MOV    DL,BL
       MOV    AH,2
       INT    21H
;
       MOV    AH,4CH
       INT    21H
MAIN   ENDS
;
DATA   SEGMENT
AAA    DW     'AB'
DATA   ENDS
       END ENTRY

레이블 ENTRY를 정의하고 END 뒤에 붙여준 부분 참조하세요.
이렇게 하지 않으면 Emu8086이 exe파일이 아닌 bin파일을 만들어버려서 세그먼트가 제대로 안 들어갑니다.

(그건 그렇고, AB가 아니라 BA가 출력되는 프로그램이로군요.)

thekero의 이미지

드디어 문자 출력이 됐습니다..

아직은 ENTRY라는게 뭔지 모르겠지만..

bin파일로 만들지 말고 exe파일로 만들어라 이런 뜻인건가요..

확실히 EMU8086에서 컴파일이라는 버튼을 누르니 bin파일로 저장하라고 나오네요..

죄송하지만 한가지 더 질문드리면 어째서 AB가 아니라 BA가 나오는지 궁금합니다..

중간에 MOV DL,BH는 A가 들어가고 그 뒤 MOV DL,BL이 B가 들어갈텐데..

어째서 거꾸로 됐는지..

혹시 MOV BX,AAA <== 이게 BX에 등록될때 16진수값으로 4142H로 저장이 된다고 나오는데

이게 뒤바뀌는건가요..?

책이 너무 옛날꺼여서.. 현재 운영체제랑 많이 틀린가 봅니다 ㅜ_ㅜ

요즘 나오는책은 너무 어려워서.. 겨우 도서관에서 구한 책인데.. ㅜ_ㅜ

 의 이미지

1. 꽤나 옛날에 쓰던 도구/문법인지라 저도 제대로 기억은 안납니다만,
원래 어셈블리 프로그램의 끝을 지시하는 END 뒤에 프로그램의 엔트리 포인트의 레이블을 지정해야 하는 걸로 압니다.
아무래도 그게 없으니 exe파일을 만드는 걸로 인식을 못하고 그냥 bin파일로 만드는 듯하군요.

... 이게 아마 어셈블러 규약일 텐데 매뉴얼을 찾아서 확인해보려 해도 잘 안 보이네요. 예컨대 MASM같은 경우는 뒤의 엔트리 포인트 주소를 생략해도 된다고 나와있던데 말이죠.

아무튼 저렇게 쓰면 제대로 되니까 저대로 쓰세요.

2. 레이블이 무엇인지 아직 잘 모르시는 듯한데 어셈블리 계속 공부하시다 보면 언젠간 알게 될 겁니다.
(대략 조건 분기 공부할 때쯤 알려 줍니다.)

3. AB가 아니라 BA가 나오는 이유는 Endianness 때문입니다. Intel 아키텍처는 8086부터 최신 64비트 멀티코어에 이르기까지 전부 Little endian입니다.

이는 정수 값이 메모리에 저장될 때 LSB(Least Significant Byte)가 낮은 메모리주소에 들어가게 된다는 것을 의미합니다.
보통 메모리 뷰는 낮은 메모리주소를 앞에 표시하므로, 사람이 보기에 마치 바이트 순서가 뒤집힌 것처럼 보이게 됩니다.
일견 비직관적인 것처럼 보이지만 이렇게 만들었을 때 장점도 뚜렷히 있습니다.

아무튼, 그래서 DW 'AB'라고 써 놓으면 메모리 뷰에는 0x41, 0x42가 차례로 들어가지만, 이거를 BX로 읽어들이면 낮은 메모리 주소에 있는 0x41이 LSB가 되어 0x4241이 올라온다는 거죠. 여기서 BH를 읽으면 0x42가 읽혀서 'B'가 먼저 출력되는 겁니다.

4. 운영체제의 차이라기보다는 문자 그대로 CPU 차이입니다.
8086 마이크로프로세서는 1970년대 물건이라고요. -_-;; 요즘은 심지어 x86-64로 넘어가면서 어셈블리 처음 배우는 분들도 64비트 어셈블리부터 시작하는 판이라 32비트 어셈블리도 조금씩 구식이 되어가는 판에, 그냥 16비트 어셈블리도 아닌 8086이라니.

8086 어셈블리가 (당연히) 간단한 편이긴 합니다만 최신 어셈블리에 있는 많은 것들이 없고, 되려 최근에는 의미를 잃은 메커니즘이 당당히 살아있어서(ex: 세그먼트 레지스터를 이용한 20bit 어드레싱) 애초에 그걸 공부하려는 게 목적이 아닌 한 별로 공부하기 좋은 내용은 아닙니다. 엄청 오래된 레거시 프로그램을 디버깅하거나, 컴퓨터 OS 부팅 코드를 공부/작성해보는 용도 아니면 별로 쓸 데도 없어요.

일단, 제가 어셈블리를 처음 공부할 때 길잡이가 되어 주었던 책 한 권 권해드립니다.
Kip. R. Irvine의 책입니다: http://book.naver.com/bookdb/book_detail.nhn?bid=6727521
제가 처음 접했을 땐 4판이었는데 벌써 6판 나왔네요.

그리고 어셈블리를 공부하려면 일단 기본적으로 CPU와 프로그램에 대해서 어느 정도 알아야 합니다.
그 옛날 다른 선택의 여지가 없었던 시절처럼 쌩으로 부딛치는 방법도 있겠지만, 요즘에는 최소한 C언어라도 어느 정도 수준 이상으로 갈고 닦은 뒤 시작하면 도움이 많이 될겁니다.

thekero의 이미지

말씀하신 Kip. R. Irvine의 6판 책을 가지고 있습니다... 다만 아무것도 모르는 제가 보기에는 너무 힘들더라구요..

그 책의 안내에도 C언어 및 다른 언어를 알고 있는 상태에서 진행하라고 해서..

그래서 제일 쉬운 책을 고르다보니 1992년 책까지 거슬러 올라가게 됐습니다....

그래서 일단 이걸로 기본 개념을 익힌 다음에 바로 Kip. R. Irvine를 볼려고 했었는데..

그게 제 판단오류였나 봅니다..

도움말씀 주셔서 너무 감사드립니다...

참.. 어셈블리어를 공부하는 이유는 그냥 맨 밑바닥에서 프로그램이 어떻게 돌아가는지 궁금해서 입니다.

추후에는 당연히 C를 배울 생각입니다...

다시 한번 너무 감사드립니다.. 종종 질문 올릴테니 그때도 좀 부탁드리겠습니다. ^^

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.