어셈블리에서 포인터에 대한 포인터로 작업 할 때 혼동되기 쉽습니다. 인수로 전달하면
argv
진리 argv
년에는 char 또는 char** argv
포인터에 대한 포인터이며, 자신의 항목 유형에 대한 포인터로 C 배열의 부패 이후에 "문자열의 배열"또는 더 나은는 char에 대한 포인터의 배열입니다 .
이것은 문자열의 문자에 액세스하기 위해 두 개의 역 참조가 필요하고 이러한 문자열에 대한 포인터에 액세스하기 위해 하나의 문자열을 액세스해야한다고 알려줍니다.
파라미터 역순 스택에 전달되는 cdecl을 규칙을 가정하면, 우리는 argc
의 값 ebp+0ch
에 있음이 표준 프레임 포인터를 설정하는 기준 프롤로그 가정.
ebp
은 포인터의 의미를 가지고 있으므로 ebp+0ch
은 argc
값으로 다른 포인터를 얻기위한 포인터 산술 일뿐입니다.
ebp+0ch
에 C 유형을 기꺼이 쓸 경우 char***
이 될 것이므로 포인터 argv[1]
에 액세스하려면 2 개의 역 참조가 필요합니다.
코드 ESI
에 argv[1]
이 얻을 :
;typeof(ebp+0ch) = char***
mov esi, DWORD [ebp+0ch] ;1st defer, esi = argv, typeof(esi) = char**
mov esi, DWORD [esi+04h] ;2nd defer, esi = argv[1], typeof(esi) = char*
;Optional, Get a char
mov al, BYTE [esi] ;3rd defer, al = argv[1][0], typeof(al) = char
유형 확인.
소리가 혼란 스럽습니까?
그 포인터를 그려 보겠습니다!
The stack The memory
100ch | 2000h | argv 2000h | 2008h | argv[0]
1008h | 2 | argc 2004h | 2010h | argv[1]
1004h | yyyyyy | return address 2008h | file | argv[0][0..3]
1000h | xxxxxx | old frame pointer 200ch | .a\0\0 | argv[0][4..7]
2010h | -arg | argv[1][0..3]
EBP = 1000h 2014h | 1\0\0\0 | argv[1][4..7]
ebp+0ch
는 1000H + = 0CH 100ch이고 그것은 argv
값의 주소이다.
mov esi, DWORD [ebp+0ch]
은 mov esi, DWORD [100ch]
과 같으며 ESI
을 2000h로 설정합니다.
2000h는 배열 인 argv
의 값이므로 argv[0]
의 주소입니다.
argv[1]
의 주소는 4 바이트 앞에 있으므로 2000h + 04h = 2004h입니다.
mov esi, DWORD [esi+04h]
은 mov esi, DWORD [2004h]
과 같으며 2010h에 ESI
을 설정합니다.
2010h는 "-arg1"문자열의 주소입니다. 사진 위의 C 나 C++ argv[argc]
등의 준수 표준 0
해야 아니라고
주 나는 왼쪽 그 사진 중.
이들은 동일하지 않습니다. 첫 번째는'* (* (ebp + 12) +4)'를 두 번째는'* (ebp + 16)'만합니다. 역 참조 해제는 생략 할 수 없습니다. – Jester
덕분에 @ DanMašek는 우스꽝스럽게 도움이되지 못했다. – Eric
@Jester 많은 것을 감사드립니다. 나는 그것에 대해 생각할 것이다. – Eric