내 코드가 8086 & 80286 프로세서에 비해 너무 느립니다. 따라서 실제 모드 코드에 32 비트 레지스터와 명령어를 사용하기로 결정했습니다.기본 세그먼트 정의 크기를 변경하지 않고 MASM에서 32 비트 레지스터 사용
내가 할 수 있어야 할 필요가있는 것은 66h로 접두어로되어 있지만, 어셈블리 파일의 맨 위에 .386 지시문을 포함시키지 않으면 386 개의 레지스터가 MASM에서 허용되지 않는다는 것을 알고 있습니다. .
이렇게하면 386 개의 레지스터를 사용하지 않아도 프로그램이 더 이상 작동하지 않는 것으로 나타났습니다. 그것은 검은 화면에서 중단 후 DOSBox 충돌합니다. 이는 일반적으로 프로그램에서 스택 크래시 및 메모리 손상을 나타내는 동작입니다.
MASM 5.10 (내가 사용하는 버전)에 대한 설명서에서이 정보를 발견했습니다. ".MODEL 지시문 앞에 .386 지시문을 사용하면 세그먼트 정의는 32 비트 세그먼트를 정의합니다. 16 비트 세그먼트를 가진 80386 프로세서라면, .MODEL 지시문 뒤에 .386 지시문을 주어야합니다. "
저는 여기에 제 문제가 있다고 확신합니다. 세그먼트가 16 비트로 유지되도록 .MODEL 지시문을 포함해야합니다. .386 지시문을 사용하기 전에 나열된 .MODEL 지시문 (설명서가 가장 일반적인 모델로 참조 됨)을 주 어셈블리 파일에 포함하여 시도했습니다. 그들은 모두 내 프로그램을 구성하는 다른 12 개의 어셈블리 파일 중 하나에 .MODEL 지시문을 포함하지 않는다는 사실로 인해 발생할 수있는 오류를 생성합니다. 그냥 기본 .MODEL을 계속 사용하고 싶습니다.
.MODEL 지시문을 지금까지 사용할 필요가 없었습니다. 설명서에 기본적으로 사용되는 언급이 없거나 .386을 사용하면 16 비트 세그먼트가 그대로 유지됩니다.
.MODEL SMALL, .MODEL MEDIUM과 같이 많은 링커 오류 발생 모든 .MODEL COMPACT : 오류 L2002을 : 세그먼트 코드의 POS에서 0016에서 픽스 오버 플로우 : 1FA 기록 유형 : LARGE 48A8
.MODEL .MODEL HUGE는 잘 어셈블하고 연결하지만 비디오 메모리에 덤프 된 일부 쓰레기와 함께 나중에 몇 프레임짜리 프로그램이 충돌합니다. 아마도 스택 충돌입니다. 또 다른 12 개의 어셈블리 파일에 .MODEL 지시문을 포함시키지 않습니다.
가끔 내가 원하는 것은 386 개의 레지스터와 명령어를 사용할 수 있지만, 그렇지 않으면 프로그램이 항상 똑같은 동작을하기를 원합니다. 16 비트와 같은 모든 세그먼트를 처리합니다.
여기 내 메인 어셈블리 파일입니다. 어떤 모델인지 확실하지 않습니다. 아마, 아마도? 64k보다 큰 단일 세그먼트는 없으므로 그렇지 않을 수도 있습니다. 단일 스택 세그먼트와 단일 코드 세그먼트가 있지만 여러 개의 데이터 세그먼트가 있습니다. 이 모든 것은 공개되어 있으며 프로그램을 구성하는 어셈블리 파일 전체에서 공유됩니다.
theStack SEGMENT STACK
db 64 dup ('THESTACK') ;512 byte stack
theStack ENDS
varData SEGMENT PUBLIC
INCLUDE const.inc ;global constants
PUBLIC fCntr
fCntr db 0 ;A frame counter used to delay animations.
varData ENDS
frame SEGMENT PUBLIC
db scrArea dup (247d) ;64,000 byte frame buffer
frame ENDS
field SEGMENT PUBLIC
db 65535 dup ('F') ;64k buffer that holds up to 32,768 tile indexes
field ENDS
sprites SEGMENT PUBLIC
db 65535 dup ('S') ;64k buffer for animated spites
sprites ENDS
code SEGMENT PUBLIC
EXTRN SET_VGA_256:PROC,INIT_DISK_VARS:PROC,INIT_AREA:PROC,CALC_DELAY:PROC
EXTRN HANDLE_INPUT:PROC,UPDATE_SPRITES:PROC,DRAW_SPRITES:PROC
EXTRN DRAW_FIELD:PROC,WRITE_FRAME:PROC,FRAME_DELAY:PROC,EXIT2DOS:PROC
EXTRN DBG:PROC
assume cs:code,ds:varData
main PROC
start:
mov ax, varData
mov ds, ax ;Load the variable segment into ds
cld ;ensure that string operations auto-increment
call SET_VGA_256 ;Set the video mode to 320x200 256 colors.
call INIT_DISK_VARS ;Setup hard drive access variables
call INIT_AREA ;Build the area into memory from data files
call CALC_DELAY ;calculate the frame delay using the RTC
LOOP_TILL_ESC:
call HANDLE_INPUT ;Handle user input.
call UPDATE_SPRITES ;bounds check then move the sprites
call DRAW_FIELD ;draw the tiles that make up the play field
call DRAW_SPRITES ;draw all currently visible sprites
call WRITE_FRAME ;Write the frame buffer to video memory.
inc fCntr ;increment the frame counter
call FRAME_DELAY ;delay for the specified number of milliseconds
cmp bp, 1 ;Was the Esc key pressed?
jne LOOP_TILL_ESC ;If not, loop back through the main program.
call EXIT2DOS ;If so, return to DOS.
main ENDP
code ENDS
END start
다음은 .386이 사용되면 중단되는 간단한 프로그램입니다. 그것은 분홍색 픽셀로 화면을 채우기로되어 있지만 대신 그것은 검은 화면에서 멈추고 도스 박스를 충돌시킵니다.
.MODEL SMALL
.386
theStack SEGMENT STACK
db 64 dup ('THESTACK')
theStack ENDS
code SEGMENT PUBLIC
assume cs:code,ds:varData
main PROC
start:
mov ax, varData
mov ds, ax ;Load the variable segment into ds
cld ;ensure that string ops auto-increment
xor ah, ah ;select set video mode function
mov al, 13h ;320x200 256 colors
int 10h ;video mode set
mov di, 0a000h
mov es, di
xor di, di ;es:di -> vga pixel buffer
mov ah, 64d
mov al, ah ;ah & al -> pink color index byte
mov cx, 32000d ;writing 32,000 words
rep stosw ;fill the screen with pink pixels
ESC_LOOP:
in al, 60h
cmp al, 1
jne ESC_LOOP ;delay till escape key is pressed
mov ax, 40h
mov es, ax ;access keyboard data area via segment 40h
mov WORD PTR es:[1ah], 1eh ;set the kbd buff head to start of buff
mov WORD PTR es:[1ch], 1eh ;set the kbd buff tail to same as buff head
;now the keyboard buffer is cleared.
xor ah, ah ;select video mode function
mov al, 3 ;select 80x25 16 colors
int 10h ;restore VIDEO back to text mode
mov ah, 4ch ;Terminate process DOS service
xor al, al ;Pass 0 to ERRORLEVEL
int 21h ;Control returns to DOS
main ENDP
code ENDS
END start
이전에 사용한 프로그래밍 모델은 무엇입니까? 코드를 볼 수 있습니까? L2002 오류는 너무 멀리있는 기호를 참조하려고 시도했음을 나타내지 만 코드를 보지 않고는 정확히 틀린 것을 말하기 어렵습니다. – fuz
좋아요, 주 어셈블리 파일에서 수정하겠습니다. 나는 모델을 사용한 적이 없다. 그것은 무엇이든을 사용하고 있었다 디폴트. –
'.model '없이 세그먼트를 어떻게 정의합니까? '.code'와 다른 단축키를 피하고 세그먼트를 완전히 정의 할 수 있습니까? 그렇다면 16b 코드 세그먼트 안에'.386 '을 포함하는 것은 아마도'.model'없이도 작동 할 수 있습니다. 그러나 이것은 실제 MASM 지식/경험과 관련이없는 논리적 의미에 기반한 것입니다. 그리고 목표 아키텍처는 무엇입니까, 얼마나 많은 코드/데이터가 있습니까? 당신은 "작은"모델에 들어 맞습니까? (하나의 데이터 세그먼트 + 하나의 코드 세그먼트) – Ped7g