[완료] 질문_어셈블리어 call에 관한 질문 입니다.

hoongwan의 이미지

================boot.asm================
[org 0]
jmp 0x07C0:start

start:
mov ax, cs
mov ds, ax

mov ax, 0xB800
mov es, ax
mov di, 0
mov ax, word [msgBack]
mov cx, 0x7FF
; lea esi, [msgBootloader]
; call print

;print:
; push eax
;print_loop:
; mov al, byte [esi]
; mov byte [es:di], al
; inc di
; or al, al
; jz print_end
; mov byte [es:di], 0x07
; inc di
; inc esi
; jmp print_loop
;print_end:
; pop eax
; ret
paint:
mov word [es:di], ax
add di, 2
dec cx
jnz paint
read:
mov ax, 0x1000
mov es, ax
mov bx, 0

mov ah, 2
mov al, 1
mov ch, 0
mov cl, 2
mov dh, 0
mov dl, 0
int 0x13
jc read

jmp 0x1000:0000

;msgBootloader db "succeed into the Bootloader", 0
msgBack db '.', 0x07
times 510-($-$$) db 0
dw 0xAA55

=====kernel.asm==================================
[org 0]
[bits 16]

start:
mov ax, cs
mov ds, ax
xor ax, ax
mov ss, ax

mov ax, 0xB800
mov es, ax
mov di, 80*2*10+10*2
lea esi, [msgKernel]
call print

jmp $
print:
push eax
print_loop:
mov al, byte [esi]
mov byte [es:di], al
inc di
or al, al
jz print_end
mov byte [es:di], 0x06
inc di
inc esi
jmp print_loop
print_end:
pop eax
ret

msgKernel db "From now on, We are in Kernel", 0

처음에는 boot.asm에서 메시지 1개, kernel.asm에서 메시지 1개를 출력하려고,
boot.asm에 print:레이블을 써서 출력 하려고 했는데 무슨 탓인지 저위치에서 call을 하니까 [주석처리한 부분..]kernel쪽 메시지가 올라오지 않습니다....
원래는 boot.asm에 call명령을 쓰지않고 위 코드의 paint: 레이블 같이 점으로 화면은 채우는 코드가 있었습니다.
여러번 코드 수정하고, 별에별짓 다해보다가 책에 있는 구조대로 print: 레이블 빼고 paint:로 바꾸니까 되는군요...

제목을 call 명령에 관한 질문이라고 했지만 사실 정확히 뭣 때문에 안되는지 모르겠습니다. 단지 call을 빼니까 안뜨던 메시지가 떠서 call때문인가? 라고 생각한 것입니다.
왜 저기서 call명령어를 넣은 온래 source는 kernel을 불러오지 못할까요??

chadr의 이미지

안되는것이 당연합니다.:)

; lea esi, [msgBootloader]
; call print

이를 이용해서 print를 call했습니다.

그리고 바로 아래에 있는 print 레이블로 점프후 call이 다 끝나고 ret 명령어가
call 할 때 스택에 푸시한 메모리 주소의 다음 주소를 eip에 넘겨 줍니다.

그러면 cpu는 그 다음 명령어를 수행합니다. 그 명령어가 바로

;print:
;push eax

이 코드에서 두번째 코드가 되는 것입니다.

즉, 똑같은 코드가 다시 call을 안했지만 실행되고 맨 마지막에 또 ret으로 인해서 스택에서
원래로 돌아갈 메모리 주소를 eip에 넣지만 이는 엉뚱한 메모리 주소가 되는 것입니다.

그래서 cpu는 엉뚱한 메모리 주소로 점프를 하게 되고 그대로 crash하는 것입니다.

해결 방법은 절대로 실행이 되지 않는 위치에 print 코드를 넣어주시면 됩니다.

jmp 0x1000:0000 코드 다음으로 넣어주시면 되겠네요.

-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.

hoongwan의 이미지

답 주신분 알림글을 보니 콜 때문에 일어난 일이 아니라 콜을 잘못 쓴 저때문이군요..
이해하고 넘어갔다고 생각했지만.. 어째 하면 할 수록 새롭습니다. ㅎ
정확한 답변 감사합니다 ㅎ

아., 그리고 전부터 궁금한게 있었는데, 왜 push eax를 해주나요?..
eax는 연산할 때 필요에 따라 값을 넣었다 뺏다 하던데...
굳이 값을 보존하는 이유를 모르겠네요...

...

chadr의 이미지

많은 어셈블리어 명령어 중 명령어 연산 결과를 eax에 자동으로 넣어주는 명령어가 많습니다.
그리고 eax 레지스터는 어떤 명령어를 실행하기 위해서 필요한 파라메터 등을 넣는데 많이 쓰입니다.

이렇게 때문에 어떤 함수가 call되어서 수행중에 다른 함수를 call 할 경우 caller의 상태를 백업 해야만
합니다.

필요때마다 push-pop을 해도 되지만 어차피 쓸것이므로 그냥 미리 스택에 push해서 백업해놓는 편이
편하기 때문에 그렇게 씁니다. 물론 eax를 전혀 안쓰는 경우에는 스택에 백업 할 필요가 없구요.
또한 eax뿐만 아니라 callee에서 다른 레지스터를 건든다면 건드는 레지스터도 백업해야합니다.

-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.

hoongwan의 이미지

감사합니다...오늘도 많은 지식 얻어감니다.

...

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.