2013-03-22 6 views
1

나는 간단한 프로그램을 가지고 있는데, 이는 PCI configuration space (첫 번째 PCI 장치 만)입니다. 그러나 그것은 작동하지 않습니다. YASM :PCI 장치가 어셈블리 언어로 검사 됨

[use 32] 
    [org 0x7c00] 

start: 
    mov  ah, 0x3 
    int  0x10  ;clear screen 
;forming the PCI address 

    push ax 
    or  ah, 10000000b 
    xor  al, al 
    or  al, 00000001b 
    shl  eax, 16 
    pop  ax 
    xor  al, al 
    xor  ah, ah 
    push eax 
    out  0xcf8, eax 
    in  eax, 0xcfc 
    mov  edi, field 
    stosd 
    mov  si, di 
    call print_str 
    ret 
field:  
print_str: 
;print a string in si 
    mov  ax, 0xb800 
    mov  es, ax 
    xor  di, di 
    mov  cx, 128 
    rep  movsw 
    ret 

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

감사 : 여기

18: warning: value doesnt fit in 8 bit fild 
19: warning: value doesnt fit in 8 bit fild 

는 코드입니다.

P. 에뮬레이션을 위해 Bochs를 사용하고 YASM을 어셈블러로 사용합니다.

답변

3

out 또는 in을 16 비트 즉시 포트 번호와 함께 사용할 수 없습니다. inout에는 8 비트 즉시 포트 번호 만 가능합니다.

그래서 당신이 dx에 포트 번호를 저장해야합니다

 
mov  edi,field 
stosd 
mov  si, di 
call print_str 
ret 
field:  
print_str: 
;print a string in si 
mov  ax, 0xb800 
mov  es, ax 
xor  di, di 
mov  cx, 128 
rep  movsw 
ret 

편집 :

 
mov  dx,0xcf8 
out  dx,eax 
in  eax,dx 

다음, 블록 아래에 몇 가지 문제가 있습니다 고정 오타가되어야합니다 : "예약하지 마십시오". 수정 됨.

위의 블록에는 몇 가지 문제가 있습니다. 먼저, edi을 메모리의 인덱스로 사용하여 저장하는 것으로 가정합니다. 그러나 그 목적을 위해 메모리를 예약하지 않으므로 mov ax,0xb800 (66 b8 00 b8, 정확히 4 바이트)을 (즉시 16 비트 포트 번호를 처음 수정 한 경우)에서 eax으로 읽은 값으로 기꺼이 덮어 씁니다.

 
field: 
times 4 db 0 ; to reserve 4 bytes (but you may need more, 
      ; keep reading to understand why) 
:

 
push cs 
pop es 

가 메모리를 예약하려면 : 부트 로더 코드에서 기본적으로 es 점은, 어쨌든,으로 먼저 설정해야 할 수있는 위치

둘째, 나는 정확히 모르겠어요

하지만 아직 충분하지 않습니다. 0xcfc에서 읽은 번호를 으로 eax으로 인쇄하려면 먼저 문자열로 변환해야합니다.

Is this code correct (Number plus number, then print the result)

참고가 많은 바이트가 필요합니다 (하나 진수 또는 16 진수) 꽤 자주 아이디어를 얻을 SO에 요청, 그래서 일부 이전 답변을 확인한다 86 어셈블리에 문자열로 숫자를 변환 rep movsw (아래 참조)을 사용하려면 숫자에 문자가 있거나 2 x 문자 수만큼.

그런 다음 비디오 메모리에 쓰는 코드에서 변환없이 비디오 메모리에 이진 값을 복사하는 것처럼 보입니다. 따라서 위의 2 가지 수정을 수행하면 첫 번째 행의 처음 64 자에 색이있는 문자가 표시됩니다. my recent answer to a SO question on printing a string without OS을 참조하십시오. 두 가지 방법으로 예제 코드가 있습니다.

희망이 도움이됩니다.

+0

감사합니다. 그러나 프로그램은 아무것도하지 않습니다 (예를 들어 화면을 지우십시오).모든 in/out 연산이나 32 비트 ('eax '등)에 필요한가? – Vanzef

+0

@Vanzef 코드에 더 많은 문제점에 대한 설명이 추가되었습니다. ['in'] (http://web.itu.edu.tr/kesgin/mul06/intel/instr/in.html)과 ['out'] (http://web.itu.edu.tr/kesgin /mul06/intel/instr/out.html)은 8 비트의 즉각적인 포트 주소 만 허용하며'al','ax' 및'eax'도 마찬가지입니다. 16 비트 포트 주소의 경우 'dx'를 사용해야합니다. – nrz

+0

... 당신은'비트 32 '를 원하지 않습니다! –