C에서 스크린 메모리에 쓸 수 없습니다.
저는 C가 자바에 이어 두 번째로 높은 수준의 프로그래밍 언어이기 때문에 매우 생소합니다.저는 기본적인 것들을 거의 다 이해했지만, 어떤 이유에서인지 화면 메모리에 한 글자도 쓸 수 없습니다.
이 프로그램은 120mhz로 실행되는 Am486-DX4-100에서 DOS용 Turbo C를 사용하여 컴파일됩니다.그래픽 카드는 Trio32 칩을 사용하는 매우 표준적인 VLB 다이아몬드 멀티미디어 스텔스 SE입니다.
OS의 경우 ISO 코드 페이지가 로드된 PC-DOS 2000을 실행하고 있습니다.표준 MDA/CGA/EGA/VGA 스타일 80열 텍스트 모드로 컬러로 실행 중입니다.
다음은 제가 작성한 프로그램입니다.
#include <stdio.h>
int main(void) {
unsigned short int *Video = (unsigned short int *)0xB8000;
*Video = 0x0402;
getchar();
return 0;
}
말씀드린 것처럼 저는 C에 대해 매우 생소한 사람이기 때문에, 제가 이해할 수 있는 방법에 대한 확실한 출처를 찾을 수 없었습니다.
제가 알기로는 x86 플랫폼의 리얼 모드에서는 텍스트 모드의 화면 메모리가 0xB8000에서 시작합니다.각 문자는 2바이트로 저장되며, 하나는 문자용이고 다른 하나는 배경/포그라운드용입니다.이 방법은 0x0402(빨간 미소 얼굴이어야 함) 값을 0xB8000에 쓰는 것입니다.이렇게 하면 화면 왼쪽 상단에 표시됩니다.
화면이 스크롤되어 실행 시 캐릭터가 즉시 제거될 수 있는 두 가지 방법을 고려했습니다.이 문제를 해결하기 위해 다음을 시도했습니다.
- 루프를 사용하여 이 값 반복 쓰기
- 조금 더 적어주세요.
저는 제가 기억에 쓴 값을 읽고 인쇄할 수 있기 때문에 분명히 기억 속 어딘가에 있지만, 어떤 이유로든 화면에 아무것도 표시되지 않습니다.제가 분명히 뭔가 잘못하고 있지만, 무엇이 문제가 될 수 있는지 모르겠습니다.더 필요한 세부사항이 있으면 문의해주시기 바랍니다.가능한 도움을 주셔서 감사합니다.
실제 모드에서는 메모리의 첫 번째 전체 1MiB를 처리하기 위해 20비트 세그먼트:오프셋 주소 지정이라는 메커니즘이 사용됩니다.0xb8000은 실제 메모리 주소입니다.당신은 a라는 것을 사용할 필요가 있습니다.far실제 모드 분할로 메모리 주소를 지정할 수 있는 포인터입니다.다양한 유형의 포인터가 이 스택 오버플로 응답에 설명되어 있습니다.
0xb8000은 0xb800의 세그먼트와 0x0000의 오프셋으로 나타낼 수 있습니다.실제 주소를 가져오는 계산은 세그먼트*16+오프셋입니다.0xb800*16+0x0000=0xb8000.이를 염두에 두고 다음을 포함할 수 있습니다.dos.h다음을 사용합니다.MK_FP C 매크로를 사용하여 초기화far지정된 세그먼트 및 오프셋의 해당 주소에 대한 포인터입니다.
설명서에서 MK_FP는 다음과 같이 정의됩니다.
MK_FP() 먼 포인터 만들기
#include <dos.h> void far *MK_FP(seg,off); unsigned seg; Segment unsigned off; OffsetMK_FP()는 구성 요소 세그먼트 'seg' 및 오프셋 'off' 부분에서 먼 포인터를 만드는 매크로입니다.
반환: 먼 포인터입니다.
코드는 다음과 같이 작성할 수 있습니다.
#include <stdio.h>
#include <dos.h>
int main(void) {
unsigned short int far *Video = (unsigned short int far *)MK_FP(0xB800,0x0000);
*Video = 0x0402;
getchar();
return 0;
}
메모리 세그먼트 주소는 사용되는 비디오 모드에 따라 달라집니다.
0xA0000 for EGA/VGA graphics modes (64 KB)
0xB0000 for monochrome text mode (32 KB)
0xB8000 for color text mode and CGA-compatible graphics modes (32 KB)
VRAM에 직접 액세스하려면 세그먼트 및 오프셋 주소를 저장할 32비트 포인터가 필요합니다. 그렇지 않으면 힙을 엉망으로 만들 수 있습니다.이로 인해 일반적으로 정의되지 않은 동작이 발생합니다.
char far *Video = (char far *)0xb8000000;
참고 항목:가깝고도 멀고 거대한 포인터는 무엇입니까?
@는 @stacker 지듯이비적환, 에▁@▁as▁to▁16▁put▁need▁carefully합다stack니▁af▁the▁pointer비stack▁inai-ment▁you▁you야해▁the할-outk가당▁pointed▁@,. AFAIK를 입력해야 합니다.FAR키워드 (맙소사, 정말 향수야.
또한 "거대한" 메모리 모델로 컴파일하지 마십시오.모든 32비트 포인터가 자동으로 20비트로 "표준화"되기 때문에 원격 주소 지정과 호환되지 않습니다.대용량 메모리 모델을 선택해 보십시오.
언급URL : https://stackoverflow.com/questions/47588486/cannot-write-to-screen-memory-in-c
'programing' 카테고리의 다른 글
| ASP.NET 4.5 프로젝트를 위해 Visual Studio 2015와 함께 Grunt, Bower, Gulp, NPM 사용 (0) | 2023.07.16 |
|---|---|
| Github: 업스트림 분기를 포크로 가져옵니다. (0) | 2023.07.16 |
| SpringBoot가 다중 모듈 Java 애플리케이션의 다른 모듈에서 RestController를 인식하지 못합니다. (0) | 2023.07.16 |
| C 및 C++ 함수 서명에 사용되는 휴대용 USED 매개 변수 매크로 (0) | 2023.07.16 |
| SQL Server에서 커서를 사용하는 것이 잘못된 관행으로 간주되는 이유는 무엇입니까? (0) | 2023.07.16 |