[Assembly] 메모리 주소/접근

gunha·2024년 10월 11일
0

Assembly

목록 보기
5/5

메모리 주소의 표현 방법

  • 인텔 32비트에서는 주소 값을 32비트로 표현 할 수 있다.
  • 어셈블리어어에서는 메모리에 []를 통해서 접근할 수 있다.
    • ex) address가 00420000 이라면 [420000]으로 접근 할 수있다.(앞의 00은 생략)
    • 어셈블리어의 숫자는 10진수가 아닌 16진수를 뜻한다(보통)

예시 코드

mov [420000] , al
; al 레지스터의 값을 메모리주소 420000에 넣는다.
; **뒤의 값을 앞의 것에 넣는다
; 메모리에서 메모리로는 보낼 수 없다. ex) mov [메모리], [메모리]
;데이터를 복사하기 위해서는 레지스터에 넣어놓고 그 값을 다른 메모리로 보내는 방식으로 사용한다.



mov al , [4020000] / mov [4020001], al

메모리 크기 지정

  • PTR 은 포인터를 뜻한다
  • DWORD 는 4BYTE(32bits)
  • WORD 는 2BYTE(16bits)
  • BYTE는 1BYTE(8bits)
  • Word는 컴퓨터에서 기본적으로 사용하는 단위를 말한다
  • 32비트 어셈블리어인데 word는 2byte(16bits)인 이유는 원래 기본이 16bits 어셈블리어에서 확장된 형태라서 그렇다.
  • mov [402000], eax => mov dword ptr [402000], eax로 바뀌는 이유는 eax의 크기가 dword(32bits) ptr로 정해져있어서 크기를 정해줘야해서 바뀌는 것이다.
  • heap dump에서 우클릭으로 메모리의 데이터를 임의로 바꿀수있다. (올리디버거의 기능/ 단축키 ctrl + E/ KEEP SIZE CHECK)

예시코드


mov dword ptr ds:[4020000], eax
; eax의 값 : 75459191
; 결과
; 00402000 address의 heap dump의 결과로
; ptr 00402000, 00402001, 00402002, 00402003 이 지정된다.
; 91 91 45 75
; intel은 리틀 엔디안 방식을 사용해서 데이터가 거꾸로 들어가게 된다.
; 어셈블리어에서 ds는 "Data Segment"를 나타내는 세그먼트 레지스터이다. x86 아키텍처에서 메모리는 여러 개의 세그먼트로 나뉘며, 각 세그먼트는 특정 용도로 사용된다.
; x86 아키텍처에서는 메모리를 세그먼트 단위로 나누고, 각 세그먼트에 접근하기 위해 세그먼트 레지스터를 사용한다. 주요 세그먼트 레지스터는 ds, cs(코드 세그먼트), ss(스택 세그먼트) 등이 있다.

mov dword ptr ds:[4020000], 0
; 0의 크기를 알 수 없어서, 크기를 반드시 지정해두어야 한다.
; dword라 4바이트를 차지하기 때문에 [402000] , [402001], [402002], [402003] 의 값을 바꾼다.

NOP

  • NOP는 "No Operation"의 약자로, 특정 작업을 수행하지 않는 명령어이다. 이 명령어는 CPU에게 아무런 작업도 수행하지 말라는 지시를 한다.

NOP의 용도

  • 지연 : 특정 지연 시간을 만들기 위해 NOP 명령어를 여러 번 사용하여 프로세서의 실행 속도를 조절할 수 있다.
  • 패딩 : 코드의 크기를 특정 크기로 맞추기 위해 빈 공간을 만드는 데 사용할 수 있다. 이를 통해 코드의 정렬(alignment)을 유지할 수 있다.
  • 디버깅 : 디버깅 과정에서 특정 코드 부분을 일시적으로 비활성화하고자 할 때 NOP로 대체할 수 있다. 이로 인해 프로그램의 흐름을 유지하면서도 특정 코드를 실행하지 않게 된다.
  • 제어 흐름 조작 : 특정 조건문에서 코드 흐름을 조작하기 위해 사용될 수 있다. 예를 들어, 조건문을 평가하고 실행할 명령어가 없을 때 NOP를 사용하여 논리적인 흐름을 유지할 수 있다.

0개의 댓글