2011-02-17 4 views
4

나는 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를 사용하고 있습니다.

답변

4

print_inteax의 값을 출력합니다. 귀하의 코드에서 bl ->cl ->al의 할당 체인을 통해 eax (a.k.a. al)의 4 바이트 중 가장 작은 바이트 만 할당합니다. eax의 나머지 세 바이트는 초기화되지 않은 상태로 남습니다. 코드는 루틴이 시작될 때 그 세 바이트에 있었던 값을 상속합니다. 이것이 쓰레기를 버리는 이유입니다.

사용중인 모든 레지스터와 메모리 위치를 초기화해야합니다.

내 x86 어셈블리는 약간 녹슬지 만 모든 범용 레지스터를 0으로 설정하는 단일 명령은 없다고 확신합니다. 당신이 그렇게 생각한다면, 아마도 이것을 할 매크로를 작성할 수있을 것입니다.

+0

ASM 프로그래머/컴파일러는 사용하려고하는 레지스터 만 초기화한다고 생각합니다. 지금 당장 ASM을 배우는 것에 관심이 있기 때문에 한번에 모든 것을 초기화 할 것이고, 이것들과 같은 버그는 피하고 싶습니다. 어마 어마한 양의 ASM 코드를 작성할 생각은 없지만, C와 같은 언어가 어떻게 낮은 수준에서 작동하는지 이해하고 싶습니다. 감사. –

+0

충분히 공정합니다. 이것은 단지 학습 일 뿐이므로 한 가지 최첨단 방법은 작성한 모든 함수의 시작 부분에 'mov'지침을 복사하여 붙여 넣는 것입니다. – NPE

+0

저는 오늘 새로운 것을 배웠습니다. 그리고 이것에 대해 논평하는 것이 관련이 있다고 생각합니다. 내 코드의'PUSHA' 명령 (NASM에 의해'PUSHAD '으로 대체 됨)은 모든 레지스터 값을 한 순서로 스택에 푸시합니다. 이제 나는 레지스터를 내 자신의 값으로 초기화 할 책임이있다. 함수가 반환되기 전에 스택에서 doubleword를 'PUSHAD'의 역순으로 레지스터로 팝하는 'POPA'(이는 'POPAD'로 대체 됨)를 호출 할 수 있습니다. 따라서 레지스터에서 이전 데이터를 잃어 버릴까 봐 걱정할 필요가 없습니다. –

2

예, 필수입니다.

어셈블리에서 아무 것도 수행되지 않습니다.
모든 등록을 원하는 방식으로 초기화해야합니다.

관련 문제