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
실제로 어떤 명령이 실행됩니까? 'add eax, [N]'은 고정 주소에서 읽습니다. 그래서 처음으로 segfault하지 않으면 segfault해서는 안됩니다. 디버거를 사용하여 단일 단계를 수행하고 실수했을 때 regs/mem에있는 내용을 확인하십시오. –
여기서 가장 명백한 문제는 문자열을 읽지 않고 포인터를 증가시키고 0과 비교한다는 것입니다. (그리고 [e]는 기하학적으로 증가합니다. 왜냐하면'[N]'이 선형 적으로 증가하기 때문입니다.) –
이것은 cmp 라인에서 죽습니다. 당신 말이 맞아요. 제가 가지고있는 라인은 캐릭터 자체가 아니라 예상되는 값과 주소 (희망적으로 캐릭터의 주소)를 비교합니다. 내가 cmp [eax], dword 0일까요? – Eric