어셈블리어 공부하는데 책이 너무 비싸서 그래도 해석 가능한 수준으로 공부하고 돈 모아서 책을 사려고 하는데
아는 선배가 그렇게 어셈 공부하려면 간단한 프로그램 짜서 어셈코드로 돌려서 비교해서 공부해보라고 하더라고
여러 사이트나 블로그 참고해보면서 공부하고 있는데 나름 해석이 되는것도 있고 안되는 것도 있는데
instruction 을 공부하고 운영체제는 리눅스가 편해서 gcc -S 옵션 주면서 어셈코드로 보고 gdb로 한동안 역어셈 코드도 보고 공부하고 있는데
(%esp, %ebp 등의 역할등은 알고 있음.)
AT&T 문법이야.
movl $0x804889, (%esp)
이게 정확히 뭔 뜻인지 모르겠네.. %esp 에 $0x804889 에 있는 value 를 넣으라는건가??
그리고 그 %esp 의 주소가 gdb 에서 info reg esp 를 치면 나오는 주소인건가??;;;;;
이 코드가 어디서 나왔냐면
puts("TEST"); 인데
역 어셈하면 해당 부분이 밑 처럼 나오거든?? 근데 왜 %esp 에 넣는건지 또 (%esp) 랑 %esp 차이점이 뭔지 잘 모르겠음...;;
0x08048607 <main+20>: movl $0x804889f,(%esp)
0x0804860e <main+27>: call 0x804844c <puts@plt>
해당 부분을 gdb로 까보면
(gdb) x/s 0x804889f
0x804889f <__dso_handle+15>: "TEST"
이니깐 puts() 에 "TEST"가 인자로 들어가는 것으로 대충 알긴 하는데 매번 이런식으로 넘어가는게 알맞지 않은 것 같아서..
movl $0x804889f,(%esp) 이걸 정확히 어떻게 해석해야할지 모르겠음.. %esp 의 주소에 $0x804889f 의 주소에 담고 있는 값을 넣어라??
%esp 의 주소가 가르키는 값에 $0x804889f의 주소에 담고 있는 값을 넣어라???
사실 저게 그냥 주소같아 보여서 주소처럼 읽히는거지 만약에 $0x804889f 자체가 value 라면 어떻게 받아들여야하는거지???ㅠㅠㅠ
mov instruction 은 값을 넣어주는 역할로 알고있는데;; %esp 에 값을 넣으면 어쩌자는거지???;; 근데 그게 갑자기 뭘 어떻게 알아가지고
그걸 인자로 참고한다는건지 이해가 안감..
그리고 인자를 받을 때 Kernel 마다 받는 형식이 조금씩 다른 것 같은데
call function() 되기 전에 push 로 인자를 막 넣어주는 경우도 있고
저런식으로 현재 스택 포인터를 가르키는 %esp 에 mov 명령을 내리는 경우도 있고
참 ㅡ.ㅡ;; 헷갈린다.. ㅠㅠ
정리
1. movl $0x804889, (%esp) 를 어떻게 해석해야하는가
2. %esp 와 (%esp) 의 차이점을 어떻게 받아들여야하는가 (선배가 주소와 값 차이라고 하는데 그게 잘 안느껴짐;;;)
3. 함수 call 하기 전에 인자를 넣어주는 것이 push 도 있고 저런식으로 %esp 에 mov 때려서 인자로 참고하는 방식들이 있는데
이런 방식들이 서로 무슨 차이가 있는지, 또 뭔 재주로 저걸 인자로 알고 해석하는건지....
도움 주면 매우 감사~~!! ㅠㅠ 위키독스보고 더 공부해야겠당..
아는 선배가 그렇게 어셈 공부하려면 간단한 프로그램 짜서 어셈코드로 돌려서 비교해서 공부해보라고 하더라고
여러 사이트나 블로그 참고해보면서 공부하고 있는데 나름 해석이 되는것도 있고 안되는 것도 있는데
instruction 을 공부하고 운영체제는 리눅스가 편해서 gcc -S 옵션 주면서 어셈코드로 보고 gdb로 한동안 역어셈 코드도 보고 공부하고 있는데
(%esp, %ebp 등의 역할등은 알고 있음.)
AT&T 문법이야.
movl $0x804889, (%esp)
이게 정확히 뭔 뜻인지 모르겠네.. %esp 에 $0x804889 에 있는 value 를 넣으라는건가??
그리고 그 %esp 의 주소가 gdb 에서 info reg esp 를 치면 나오는 주소인건가??;;;;;
이 코드가 어디서 나왔냐면
puts("TEST"); 인데
역 어셈하면 해당 부분이 밑 처럼 나오거든?? 근데 왜 %esp 에 넣는건지 또 (%esp) 랑 %esp 차이점이 뭔지 잘 모르겠음...;;
0x08048607 <main+20>: movl $0x804889f,(%esp)
0x0804860e <main+27>: call 0x804844c <puts@plt>
해당 부분을 gdb로 까보면
(gdb) x/s 0x804889f
0x804889f <__dso_handle+15>: "TEST"
이니깐 puts() 에 "TEST"가 인자로 들어가는 것으로 대충 알긴 하는데 매번 이런식으로 넘어가는게 알맞지 않은 것 같아서..
movl $0x804889f,(%esp) 이걸 정확히 어떻게 해석해야할지 모르겠음.. %esp 의 주소에 $0x804889f 의 주소에 담고 있는 값을 넣어라??
%esp 의 주소가 가르키는 값에 $0x804889f의 주소에 담고 있는 값을 넣어라???
사실 저게 그냥 주소같아 보여서 주소처럼 읽히는거지 만약에 $0x804889f 자체가 value 라면 어떻게 받아들여야하는거지???ㅠㅠㅠ
mov instruction 은 값을 넣어주는 역할로 알고있는데;; %esp 에 값을 넣으면 어쩌자는거지???;; 근데 그게 갑자기 뭘 어떻게 알아가지고
그걸 인자로 참고한다는건지 이해가 안감..
그리고 인자를 받을 때 Kernel 마다 받는 형식이 조금씩 다른 것 같은데
call function() 되기 전에 push 로 인자를 막 넣어주는 경우도 있고
저런식으로 현재 스택 포인터를 가르키는 %esp 에 mov 명령을 내리는 경우도 있고
참 ㅡ.ㅡ;; 헷갈린다.. ㅠㅠ
정리
1. movl $0x804889, (%esp) 를 어떻게 해석해야하는가
2. %esp 와 (%esp) 의 차이점을 어떻게 받아들여야하는가 (선배가 주소와 값 차이라고 하는데 그게 잘 안느껴짐;;;)
3. 함수 call 하기 전에 인자를 넣어주는 것이 push 도 있고 저런식으로 %esp 에 mov 때려서 인자로 참고하는 방식들이 있는데
이런 방식들이 서로 무슨 차이가 있는지, 또 뭔 재주로 저걸 인자로 알고 해석하는건지....
도움 주면 매우 감사~~!! ㅠㅠ 위키독스보고 더 공부해야겠당..
1. 그냥 %esp가 가리키는 주소에 저 상수를 때려박으라는 소리잖아 앞에 $ 있는놈은 상수야
2. 걍 %esp하면 레지스터고 (%esp)하면 이 레지스터 값이 가리키는 주소값이고
%esp가 보통 스택 포인터인데, (진짜 대충 설명하면)이제 스택이 프로시저 실행될때 어디 주소부터 이 프로시저의 스택으로 사용할지 세팅해야 하잖아 그걸 push로도 하고 mov로도 만드는데 그건 컴파일러 마음이다
즉 esp안에 push하는 $쏼라쏼라가 인자가 아니라 스택 시작지점 주소값이란 소리고, 인자값은...... 이건 자신이 없는데, 시작지점 넣어주기 전에 그 시작지점 근처에 인자값을 저장한후 넣어주는걸로 아는데... 이건 내가 잘 몰라.
횰랑// 횽!! 짱 고마워 아주 쉽게 해결되었네~~ 새해 복받을꺼야~~^__^ㅋ
$0x804889f가 인자인데 뭔 개소리인겨 이건, 문자열 주소로 puts 함수에서 출력하는거지.
필자는 VC 컴파일 방식과 GCC 컴파일 방식을 비교해보길 바란다.
간단하게 말하면 VC는 스택을 미리 잡지 아나히고 gcc는 스택을 미리 잡는다.
뭐 어슐횽 말이 맞는거같다 어설피 알면 버로우 해야지