2012-07-25 7 views
-1

이 프로그램은 char 포인터를 소문자로 변환합니다. Visual Studio 2010을 사용하고 있습니다.x86 소문자로 변환

이 질문은 다른 질문에서 비롯된 것이지만 훨씬 더 간단하고 이해하기 쉽습니다. 나는 모두 소문자, 내가, 처리되지 않은 예외 ... 액세스 위반을 받고 유지로와 괄호 아무것도하지 않고 토큰에 주소를 포함 레지스터를 변경하기 위해 노력하고있어 내 또는 명령에서

int b_search (char* token) 
{ 
__asm 
{ 
mov eax, 0   ; zero out the result 
mov edi, [token]  ; move the token to search for into EDI 
MOV ecx, 0 

LOWERCASE_TOKEN:   ;lowercase the token 
OR [edi], 20h 
INC ecx 
CMP [edi+ecx],0 
JNZ LOWERCASE_TOKEN 
MOV ecx, 0 

, I 오류는 발생하지 않지만 소문자는 발생하지 않습니다. 어떤 충고? 이것은 다른 질문의 일부 더 큰 코드의 일부이지만이 솔루션 만 필요했기 때문에 문제가 발생했습니다.

+0

작동합니다 당신이 어셈블리를 사용해야합니까? 이미 'tolower (char)'가 있습니다. – chris

+0

조언이 필요하십니까? 코드를 디버깅하십시오. 우선,'edi'에서'token'의 값을 얻고 있습니까? –

+0

@chris 숙제 문제, 아마도. – Wug

답변

0

코드는 첫 번째 문자 (또는 [edi], 20h) 만 변경할 수 있습니다. EDI가 증가하지 않습니다.

편집 : 해결 방법은 this thread입니다. al 대신 'dl'을 사용해보십시오.

; move the token address to search for into EDI 
; (not the *token, as would be with mov edi, [token]) 

mov edi, token  

LOWERCASE_TOKEN:   ;lowercase the token 
    mov al, [edi] 
    ; check for null-terminator here ! 
    cmp al, 0 
    je GET_OUT 
    or al, 20h 
    mov dl, al 
    mov [edi], dl 
    inc edi 
jmp LOWERCASE_TOKEN 
GET_OUT: 
+0

작동하는지 확인하고 싶었 기 때문에 코드를 그대로 복사하고 붙여 넣었습니다. 두 번째 코드가 나에게 'mov [edi], al'을 쳤기 때문에 코드가 복사되지 않습니다. 'al'의 값은 실제로 소문자입니다. 그러나 어떤 이유로 든 나는 두 번째로 [edi]를 사용할 수 없습니다. 그것은 처음 겪었지만, 두 번째'[edi]와 나는 소리 쳤다. – gooberdope

+0

@gooberdope 코드가 소리 쳤다 고요? 프로그래밍 컨텍스트에서 좀 더 구체적이어야한다고 생각합니다. –

+0

@AlexeyFrunze 원래 질문에서 말했듯이 처리되지 않은 예외/액세스 위반 오류가 발생합니다. 이것은 내 컴퓨터가 내게 소리 지르는 것입니다. – gooberdope

0

데이터를 레지스터에로드하고 거기에서 조작 한 다음 결과를 다시 메모리에 저장합니다.

int make_lower(char* token) { 
    __asm { 
     mov edi, token 
     jmp short start_loop 
    top_loop: 
     or al, 20h 
     mov [edi], al 
     inc edi 
    start_loop: 
     mov al, [edi] 
     test al, al 
     jnz top_loop 
    }  
} 

그러나 대문자로의 변환에는 다소 결함이 있습니다. 예를 들어 입력에 제어 문자가 포함되어 있으면 대문자가 아니며 대문자가 아니며 소문자로 변환되지 않습니다.

0

다른 많은 OR 연산자가 두 개의 메모리 또는 상수 매개 변수를 허용하지 않는다는 것이 문제입니다. 즉 의미 OR 연산자는 단지 다음과 같은 매개 변수를 가질 수

OR register, memory 
OR register, register 
OR register, constant 

번째 문제는 상기 OR 않은 메모리, 레지스터에 그 결과를 저장하는 것이다. 대괄호가 설정된 경우 액세스 위반이 발생하는 이유는 무엇입니까? 괄호를 제거하면 매개 변수는 정상이지만 소문자를 메모리에 쓰지 않습니다. 그래서 다른 레지스터를 사용하여 편지를 복사 한 다음 OR를 사용하십시오. 예를 들어 :

mov eax, 0   ; zero out the result 
mov edi, [token]  ; move the token to search for into EDI 
MOV ecx, 0 
LOWERCASE_TOKEN:   ;lowercase the token 
MOV ebx, [edi]  ;## Copy the value to another register ## 
OR ebx, 20h   ;## and compare now the register and the memory ##  
MOV [edi], ebx  ;##Save back the result ##  
INC ecx  
CMP [edi+ecx],0  
JNZ LOWERCASE_TOKEN  
MOV ecx, 0 

는 ^^

관련 문제