나는 Paul Carter의 pcasm 책을 읽고 있습니다. 그것은 NASM, 내 어셈블리 코드를 호출하는 C 드라이버 응용 프로그램 및 어셈블리에서 기본 I/O를 쉽게 수행 할 수있는 컴패니언 라이브러리를 사용합니다.C에서 호출 된 어셈블리 코드에서 CPU 레지스터를 초기화해야합니까?
이 같은 C에서 호출됩니다 내 함수가 모습입니다 :
segment .text
global _asm_main
_asm_main:
enter 0,0 ; setup routine
pusha
mov bx, 0034h ; bx = 52 (stored in 16 bits)
mov cl, bl ; cl = lower 8-bits of bx
mov eax, ecx
call print_int
popa
mov eax, 0 ; return back to C
leave
ret
print_int
함수는 정수로 eax
에서 값 저장소를 인쇄합니다. 하지만이 표준 출력에 쓰레기를 출력 :
4200244
내가 그것을 사용하기 전에 mov ecx, 0000h
으로 0으로 ECX 레지스터를 초기화하면, 내가 예상 출력을 얻을 것이다 :
52
이 초기화가 항상 필요하다, 그렇다면 C 또는 NASM에서 모든 레지스터를 0 (또는 사용자 정의 이니셜 라이저)로 초기화하는 빠른 방법이 있습니까?
저는 XP32, MinGW 4.4.0 및 NASM 2.09.04를 사용하고 있습니다.
ASM 프로그래머/컴파일러는 사용하려고하는 레지스터 만 초기화한다고 생각합니다. 지금 당장 ASM을 배우는 것에 관심이 있기 때문에 한번에 모든 것을 초기화 할 것이고, 이것들과 같은 버그는 피하고 싶습니다. 어마 어마한 양의 ASM 코드를 작성할 생각은 없지만, C와 같은 언어가 어떻게 낮은 수준에서 작동하는지 이해하고 싶습니다. 감사. –
충분히 공정합니다. 이것은 단지 학습 일 뿐이므로 한 가지 최첨단 방법은 작성한 모든 함수의 시작 부분에 'mov'지침을 복사하여 붙여 넣는 것입니다. – NPE
저는 오늘 새로운 것을 배웠습니다. 그리고 이것에 대해 논평하는 것이 관련이 있다고 생각합니다. 내 코드의'PUSHA' 명령 (NASM에 의해'PUSHAD '으로 대체 됨)은 모든 레지스터 값을 한 순서로 스택에 푸시합니다. 이제 나는 레지스터를 내 자신의 값으로 초기화 할 책임이있다. 함수가 반환되기 전에 스택에서 doubleword를 'PUSHAD'의 역순으로 레지스터로 팝하는 'POPA'(이는 'POPAD'로 대체 됨)를 호출 할 수 있습니다. 따라서 레지스터에서 이전 데이터를 잃어 버릴까 봐 걱정할 필요가 없습니다. –