2016-11-17 3 views
-1

NASM 어셈블리 언어에서 문자열 argv [1]의 길이를 계산하려고합니다. 나는 내가 바른 길에 있다고 생각한다. 나는 eax를 등록하기 위해 argv [1]의 주소를 옮겼다. 그리고 이제 그것을 바이트 단위로 옮기고 null 문자열 터미네이터와 비교하기를 원한다.어셈블리 (NASM)의 문자열을 반복합니다.

언제나 null 비교에서 segfaults 코드를 실행합니다. 메모리 인덱싱이 정확하지 않습니까?

* 면책 조항 : 이것은 많은 숙제의 작은 부분입니다. 몇 가지 힌트와 GDB의 도움 후

segment .bss 

N: resd 1     ;counter for size of argv[1] 

segment .text 
    global asm_main 

asm_main: 
    enter 0,0    ;setup 
    pusha     ;save all registers 

    mov eax, dword [ebp+8] ;argc to eax 

    mov ebx, dword [ebp+12] ; address of argv to ebx 
    mov eax, dword [ebx+4] ; address of argv[1] to eax 

    mov [N], dword 0  ; N = 0 

    .loop: 

    add eax, [N]   ; advance index by N 
    cmp eax, dword 0  ; check for end of string 
    je .endloop   ; break out of the loop if we're done 


    add [N], dword 1  ; N++  

    jmp .loop    ; loop back for next char 

    .endloop: 

popa 
mov eax, 0 
leave 
ret 
+1

실제로 어떤 명령이 실행됩니까? 'add eax, [N]'은 고정 주소에서 읽습니다. 그래서 처음으로 segfault하지 않으면 segfault해서는 안됩니다. 디버거를 사용하여 단일 단계를 수행하고 실수했을 때 regs/mem에있는 내용을 확인하십시오. –

+1

여기서 가장 명백한 문제는 문자열을 읽지 않고 포인터를 증가시키고 0과 비교한다는 것입니다. (그리고 [e]는 기하학적으로 증가합니다. 왜냐하면'[N]'이 선형 적으로 증가하기 때문입니다.) –

+0

이것은 cmp 라인에서 죽습니다. 당신 말이 맞아요. 제가 가지고있는 라인은 캐릭터 자체가 아니라 예상되는 값과 주소 (희망적으로 캐릭터의 주소)를 비교합니다. 내가 cmp [eax], dword 0일까요? – Eric

답변

3

은, 루프는 이제 다음과 같습니다 인덱스를 증가 N을 사용하여

mov [N], dword 0  ; N = 0 

    .loop: 

    cmp [eax], byte 0  ; check for end of string 
    je .endloop  

    add eax, dword 1  ; advance index by 1 byte 
    add [N], dword 1  ; N++  

    jmp .loop    

    .endloop: 

바보였다. 나는 1 씩 증가해야했습니다.

+2

별도의 카운터가 필요하지 않습니다. 루프 다음에'sub eax, start_of_string'을 할 수 있습니다. (루프 카운터를 피할 수 있으면 루프 카운터를 유지하지 마십시오. 정말 느립니다. N을 레지스터에 유지하거나 완전히 피할 때보 다 대부분의 Intel CPU에서 코드가 거의 정확히 6 배 더 느리게 실행됩니다. 루프로 운반 된 종속성 체인에 저장소/재로드 왕복을 넣고 저장소 전달 시간은 Intel SnB 제품군 CPU에서 5 사이클입니다.). –

+2

당신이 사용하는 데이터의 크기를 알고있는 것에 감사 드리며, JFYI :'add eax, dword 1'은 크기 지정자가 필요하지 않습니다. 한쪽에있는'eax'는 명령어의 32b 크기 컨텍스트를 시행하기 때문입니다. 그래서 이런 경우'add eax, 1'로 충분하다. 'add [N], dword 1' 아래에있는 것은 정확합니다. 적어도 하나의 측면에서 크기 지정자가 필요합니다. 모호하다면'N'도'byte' 나'word'와도 일치 할 것입니다. 바이트/단어 일뿐입니다. 그리고 + -1을하기 위해 x86은 전용 연산 코드'inc'와'dec'을 가지고', 1'의 타이핑을 저장합니다. 왜 내가 그 두 가지를 정말로 좋아하는지 모르겠다. :) – Ped7g