어셈블리 호출이 잘못된 주소로 매핑 됨

연속물

보호 모드로 전환 한 후 부트 로더에서로드 된 커널로 이동하려고합니다.

커널이 제대로로드되고 올바른 위치에 있지만 로더의 두 번째 단계가 커널의 주 함수를 호출 할 때 잘못된 주소를 호출합니다.

다음은 로더 ( loader.asm) 의 두 번째 단계입니다 .

global load_kern
extern main

[bits 32]

load_kern: 
    call main
    cli 
    hlt

그런 다음 이것을 어셈블하고 ac 개체 파일과 연결하여 elf 실행 파일을 만듭니다.

nasm -f elf32 loader.asm -o loader.o
ld -melf_i386 -n -Tos.lds loader.o os.o -o kernel.elf

이 파일을 사용하여 링크합니다.

ENTRY(load_kern);

PHDRS 
{
    headers PT_PHDR FILEHDR PHDRS;
    code PT_LOAD;
}

SECTIONS
{
    .text 0x500: ALIGN(0x100) { *(.text) } :code
    .data : { *(.data) }
    .bss : { *(.bss) }
    /DISCARD/ : { *(.eh_frame) }

}

그런 다음 이것을 kernel.elf플로피 이미지의 두 번째 섹터 (부트 섹터 뒤)에 배치합니다.

objdump kernel.elf하면 출력이 정확합니다.

os/kernel.elf:     file format elf32-i386


Disassembly of section .text:

00000500 <load_kern>:
 500:   e8 43 00 00 00          call   548 <main>
 505:   fa                      cli    
 506:   f4                      hlt    

...

00000548 <main>:
 548:   55                      push   %ebp
 549:   89 e5                   mov    %esp,%ebp
 54b:   68 5c 05 00 00          push   $0x55c
 550:   6a 05                   push   $0x5
 552:   e8 b0 ff ff ff          call   507 <write_string>
 557:   83 c4 08                add    $0x8,%esp
 55a:   eb fe                   jmp    55a <main+0x12>

main의 주소는 잘 매핑 된 것 같지만 커널 섹터를로드하고 여기로 이동하면 gdb가 표시하는 내용입니다.

   ┌─────────────────────────────────────────────────────────────────┐
  >│0x600   call   0x646                                             │
   │0x603   add    BYTE PTR [bx+si],al                               │
   │0x605   cli                                                      │
   │0x606   hlt  
...

   │0x646   leave                                                    │
   │0x647   ret                                                      │
   │0x648   push   bp                                                │
   │0x649   mov    bp,sp                                             │
   │0x64b   push   0x55c                                             |

커널은 0x500에서로드되지만 파일의 텍스트 섹션은 0x100으로 정렬되어 있으므로 코드는 0x500이 아닌 0x600 (elf 헤더 뒤)에서 시작합니다. 코드는 잘로드되지만 호출은 loader.asmmain이 시작되는 0x648 대신 0x646 사용합니다.

0x603에있을 수없는 추가 어셈블리 라인이 있습니다. 그것은 정크 명령처럼 보이며 그것을 버리는 것일 수 있다고 생각합니다. 호출 지시처럼 보입니다.

500:   e8 43 00 00 00          call   548 <main>

올바르게 해석되지만 0은 예상치 못한 추가 명령을 생성하기 위해 어떻게 든 다음 명령으로 전달됩니다. 그것이 가능성인지 확실하지 않습니다.

2 off 인 주소를 사용하는 이유를 알 수 없습니다. 이것은 커널 코드의 다른 부분에서도 발생합니다.

내가 저지른 다른 실수를 자유롭게 지적하십시오. 나는가는 동안 배우고 있습니다. 이것이 내가 연결하는 방법, 사용하는 형식 또는 다른 것과 관련이 있는지 확실하지 않습니다.


편집하다:

따라서 이것은 실제로 내 부트 로더에 문제가있는 것 같습니다.

global start

[bits 16]
[org 0x7c00]

start: jmp boot

boot:
    cli ; clear interrupts
    cld ; clear direction flag

    mov ax, 0
    mov es, ax     
    mov bx, 0x500   ; set bx to where we load the kernel

    mov al, 0x12    ; set lower byte of ax to read 18 sectors
    mov ch, 0       ; set higher byte of cx to read track 0 (first track)
    mov cl, 2       ; set lower byte of cx to read sector 2 (bootloader is sec1)
    mov dh, 0       ; set higher byte of dx to read head 0 (top side of disk)
    mov dl, 0       ; set lower byte of dx to read drive 0 (floppy drive)

    mov ah, 0x02    ; read

    int 0x13        ; call BIOS interrupt 13 to read drive
    int 0x10        ; clear screen

    jmp pm_switch

    hlt             ; this instruction should not execute


pm_switch:
    xor ax, ax      ; clear ds (used by lgdt)
    mov ds, ax

    cli
    lgdt [gdt_desc]

    mov eax, cr0
    or eax, 1        ; switch to protected mode 
    mov cr0, eax

    jmp 08h:select_jump

select_jump:
    xor eax, eax

    mov ax, 0x10        ; set data segments to data selector (0x10)
    mov ds, ax
    mov ss, ax
    mov esp, 09000h

    mov ax, 0
    mov es, ax
    ; do a far jump to set cs and go to kernel code
    jmp 08h:0x600



gdt: ; Address for the GDT
gdt_null: ; Null Segment
    dd 0
    dd 0

;KERNEL_CODE equ $-gdt
gdt_kernel_code:
    dw 0FFFFh ; Limit 0xFFFF
    dw 0 ; Base 0:15
    db 0 ; Base 16:23
    db 09Ah ; Present, Ring 0, Code, Non-conforming, Readable
    db 00Fh ; Page-granular
    db 0 ; Base 24:31

;KERNEL_DATA equ $-gdt
gdt_kernel_data:
    dw 0FFFFh ; Limit 0xFFFF
    dw 0 ; Base 0:15
    db 0 ; Base 16:23
    db 092h ; Present, Ring 0, Data, Expand-up, Writable
    db 00Fh ; Page-granular
    db 0 ; Base 24:32
gdt_end: ; Used to calculate the size of the GDT

gdt_desc: ; The GDT descriptor
    dw gdt_end - gdt - 1 ; Limit (size)
    dd gdt ; Address of the GDT


 ; pad the file to file the rest of the sector (512 bytes) and add boot sig

times 510 - ($-$$) db 0
dw 0xAA55

해결책:

내 GDT 코드 세그먼트가 16 비트로 설정되었습니다. 32로 변경하고 [bits 32]protected로 전환 한 직후에 명령을 추가 했습니다 ( select jump).

duskwuff-비활성-

를 사용하여 보호 모드 (32 비트)에 대한 코드를 생성하도록 어셈블러에 지시하고 [bits 32]있지만 프로세서가 리얼 모드 (16 비트)에서 실행 중입니다.

실행하게되는 코드는 말도 안됩니다. 많은 명령어는 실제 모드와 보호 모드에서 다르게 해석됩니다. 예를 들어, jmp실제 모드에서는 2 바이트 만 사용합니다. ( add예를 들어 0x603 에서 예상치 못한 오류가 발생하는 곳 입니다. 오류가있는 32 비트 즉치 값의 두 번째 절반입니다.)

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

Django / HTML 제출 버튼이 잘못된 페이지로 리디렉션 됨

분류에서Dev

MySQL / Hibernate가 LocalTime으로 매핑 된 열로 잘못된 데이터 검색

분류에서Dev

Rebus-Rabbitmq는 지정된 네임 스페이스 / 어셈블리의 모든 개체를 매핑합니다.

분류에서Dev

잘못된 테이블 스크래핑

분류에서Dev

Javascript WebRTC 원격 응답 설정 실패 sdp : 잘못된 상태로 호출 됨 : kHaveRemoteOffer 및 잘못된 상태로 호출 됨 : kStable

분류에서Dev

잘못된 스택 포인터로 인해 어셈블리 페이지 오류 처리기를 호출 할 수 없습니다.

분류에서Dev

Rails : 잘못된 인수 개수 (1이 주어졌고 0이 예상 됨)

분류에서Dev

Yaml If 블록으로 인해 매핑이 누락 됨

분류에서Dev

주소의 매핑 된 지역에 대한 잘못된 권한

분류에서Dev

C 프로그램에서 x86 어셈블리 함수를 호출 할 때 잘못된 행렬 값이 검색 됨

분류에서Dev

c ++-잘못된 소멸자가 호출 됨

분류에서Dev

Nasm x86 어셈블리로 제곱근을 계산할 때 잘못된 출력

분류에서Dev

Meteor + accounts-facebook이 잘못된 URL로 리디렉션 됨

분류에서Dev

Capistrano 배포 후 자산이 잘못된 릴리스로 연결됨

분류에서Dev

32 비트 프로세서에서 잘못된 어셈블리 레이블 주소

분류에서Dev

잘못된 BindingHandler가 호출 됨

분류에서Dev

wcf 프로젝트의 스트림이 MVC의 잘못된 어셈블리를 가리 킵니다.

분류에서Dev

.net 원격, 델리게이트가 잘못된 프로세스에서 호출 됨

분류에서Dev

잘못된 요소 매핑

분류에서Dev

키보드 매핑이 잘못됨

분류에서Dev

기본 Linux x86 어셈블리 최소 개수가 잘못 반환 됨

분류에서Dev

목록에서 잘못된 최소값이 반환 됨-MS Access 쿼리

분류에서Dev

헤더 위치 PHP가 잘못된 페이지로 리디렉션 됨

분류에서Dev

C 언어를 어셈블리 언어로 매핑

분류에서Dev

WebAPI 2 : 기본 GET ALL이 잘못된 매개 변수로 호출 됨

분류에서Dev

잘못된 수의 인수 (주어진 0, 1이 예상 됨)-Ruby

분류에서Dev

Azure Function이 잠시 동안 잘 실행 된 후 어셈블리를로드하지 못함

분류에서Dev

FFMPEG : 이미지가 잘못된 FPS에서 잘못로드 됨

분류에서Dev

잘못된 주소로 로컬 사이트 리디렉션

Related 관련 기사

  1. 1

    Django / HTML 제출 버튼이 잘못된 페이지로 리디렉션 됨

  2. 2

    MySQL / Hibernate가 LocalTime으로 매핑 된 열로 잘못된 데이터 검색

  3. 3

    Rebus-Rabbitmq는 지정된 네임 스페이스 / 어셈블리의 모든 개체를 매핑합니다.

  4. 4

    잘못된 테이블 스크래핑

  5. 5

    Javascript WebRTC 원격 응답 설정 실패 sdp : 잘못된 상태로 호출 됨 : kHaveRemoteOffer 및 잘못된 상태로 호출 됨 : kStable

  6. 6

    잘못된 스택 포인터로 인해 어셈블리 페이지 오류 처리기를 호출 할 수 없습니다.

  7. 7

    Rails : 잘못된 인수 개수 (1이 주어졌고 0이 예상 됨)

  8. 8

    Yaml If 블록으로 인해 매핑이 누락 됨

  9. 9

    주소의 매핑 된 지역에 대한 잘못된 권한

  10. 10

    C 프로그램에서 x86 어셈블리 함수를 호출 할 때 잘못된 행렬 값이 검색 됨

  11. 11

    c ++-잘못된 소멸자가 호출 됨

  12. 12

    Nasm x86 어셈블리로 제곱근을 계산할 때 잘못된 출력

  13. 13

    Meteor + accounts-facebook이 잘못된 URL로 리디렉션 됨

  14. 14

    Capistrano 배포 후 자산이 잘못된 릴리스로 연결됨

  15. 15

    32 비트 프로세서에서 잘못된 어셈블리 레이블 주소

  16. 16

    잘못된 BindingHandler가 호출 됨

  17. 17

    wcf 프로젝트의 스트림이 MVC의 잘못된 어셈블리를 가리 킵니다.

  18. 18

    .net 원격, 델리게이트가 잘못된 프로세스에서 호출 됨

  19. 19

    잘못된 요소 매핑

  20. 20

    키보드 매핑이 잘못됨

  21. 21

    기본 Linux x86 어셈블리 최소 개수가 잘못 반환 됨

  22. 22

    목록에서 잘못된 최소값이 반환 됨-MS Access 쿼리

  23. 23

    헤더 위치 PHP가 잘못된 페이지로 리디렉션 됨

  24. 24

    C 언어를 어셈블리 언어로 매핑

  25. 25

    WebAPI 2 : 기본 GET ALL이 잘못된 매개 변수로 호출 됨

  26. 26

    잘못된 수의 인수 (주어진 0, 1이 예상 됨)-Ruby

  27. 27

    Azure Function이 잠시 동안 잘 실행 된 후 어셈블리를로드하지 못함

  28. 28

    FFMPEG : 이미지가 잘못된 FPS에서 잘못로드 됨

  29. 29

    잘못된 주소로 로컬 사이트 리디렉션

뜨겁다태그

보관