| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 |
- approve
- ethernaut
- byte code
- Ethererum
- web assembly
- Oracle Cloud
- web3
- openzepplin
- coin flip
- TransferFrom
- Wargame
- hard fork
- audit
- ethereum
- writeup
- libray
- secureum
- NaughtCoin
- syntax
- Assembly
- Block
- EVM
- soft fork
- transaction
- chain reorganization
- Coin
- tx.origin
- Smart contract
- solidity
- ethereum virtual machine
- Today
- Total
목록Develop (7)
c0mpos3r
라인피드는 ‘Hello world’ 프로그램과 같은 콘솔 프로그램에 필수적인 요소이다. 사용자 입력이 필요한 프로그램을 만들기 시작하면 라인피드의 중요성은 더욱 커진다. 하지만 라인피드는 유지 관리가 까다로울 수 있다. 때로는 문자열에 포함시키고 싶을 때도 있다. 코드에서 해당 변수에 대한 줄 바꿈을 출력하지 않으려는 부분이 있다면 런타임에 문자열에서 이를 제거하는 추가 로직을 작성해야 한다. 메시지를 출력하는 서브루틴을 작성한 다음 나중에 줄 바꿈을 출력하는 것이 프로그램의 유지 보수성을 위해 더 좋을 것이다. 이렇게 하면 라인피드가 필요할 때 이 서브루틴을 호출하고 필요하지 않을 때는 현재 스프린트 서브루틴을 호출하면 된다. sys_write를 호출하려면 인쇄하려는 문자열의 메모리 주소에 대한 포인터..
그렇다면 왜 msg2에서 스프린트 함수를 한 번만 호출했는데 두 번째 메시지가 두 번 인쇄된 걸까?사실 한 번만 인쇄되었다. 두 번째 sprint 호출에 주석을 달아보면 무슨 말인지 알 수 있다. 출력은 두 메시지 문자열 모두이다. 하지만 이것이 어떻게 가능할까?문자열을 제대로 종료하지 않았기 때문이다. 어셈블리에서 변수는 메모리에 차례로 저장되므로 msg1 변수의 마지막 바이트는 msg2 변수의 첫 번째 바이트 바로 옆에 있다. 문자열 길이 계산은 0 바이트를 찾고 있으므로 msg2 변수가 0바이트로 시작하지 않는 한 동일한 문자열인 것처럼 계속 계산한다(어셈블리에 관한 한 동일한 문자열이다.) 따라서 문자열 뒤에 0바이트 또는 0h를 넣어 어셈블리가 카운터를 중지할 위치를 알 수 있도록 해야한다. 참..
외부 포함 파일을 사용하면 프로그램에서 코드를 이동하여 별도의 파일에 넣을 수 있다.이 기법은 깔끔하고 유지 관리가 쉬운 프로그램을 작성하는 데 유용합니다. 재사용 가능한 코드 조각은 서브루틴으로 작성하여 라이브러리라는 별도의 파일을 저장할 수 있다. 로직이 필요할 때 해당 파일을 프로그램에 포함시켜 마치 같은 파일의 일부인 것처럼 사용할 수 있다. 이 단원에서는 문자열 길 계산 서브루틴을 외부 파일로 옮기겠다. 문자열 인쇄 로직과 프로그램 종료 로직도 서브루틴으로 만들고 이 외부 파일로 옮기겠다. 이 작업이 완료되면 실제 프로그램이 깔끔하고 읽기 쉬워진다. 그런 다음 다른 메시지 변수를 선언하고 인쇄 함수를 두 번 호출하여 코드를 재사용하는 방법을 보여줄 수 있다.참고: 이 단원 이후에는 변경 사항이 ..
서브루틴은 함수이다.프로그램에서 반복 가능한 다양한 작업을 수행하기 위해 호출할 수 있는 재사용 가능한 코드 조각이다. 서브루틴은 이전에 사용한 것과 같은 레이블(예: start:)을 사용하여 선언되지만, 서브루틴에 도달하기 위해 JMP 명령어를 사용하지 않고 대신 새로운 명령어를 CALL을 사용한다. 또한 함수를 실행한 후 프로그램으로 돌아갈 때도 JMP 명령어를 사용하지 않는다. 서브루틴에서 프로그램으로 돌아가려면 RET 명령을 사용한다. 왜 서브루틴에 JMP를 사용하지 않을까?서브루틴 작성의 가장 큰 장점은 재사용이 가능하다는 점이다. 코드의 어느 곳에서나 서브루틴을 사용하려면 코드의 어느 부분에서 점프했는지, 어디로 다시 점프해야 하는지 판단하기 위한 로직을 작성해야 한다. 이렇게 하면 코드가 원..
문자열의 길이를 계산해야 하는 이유는 무엇인가 sys_write는 메모리에 출력할 문자열에 대한 포인터와 출력할 바이트 단위를 전달해야 한다. 메시지 문자열을 수정하려면 sys_write에 전달하는 바이트 단위의 길이도 업데이트해야 하며, 그렇지 않으면 올바르게 인쇄되지 않는다. 메시지 문자열을 ‘Hello brave new World’라고 수정한 다음 새 프로그램을 컴파일, 링크 및 실행한다.출력은 ‘Hello, brave’ (처음 13자)가 될 것이다. 왜냐하면 우리는 여전히 13바이트만 sys_write에 길이로 전달하기 때문이다. 이는 사용자 입력을 출력할 때 특히 필요하다. 이는 사용자 입력을 출력할 . 때 특히 필요하다. 프로그램을 컴파일할 때 데이터의 길이를 알 수 없으므로 성공적으로 출력하..
올바른 프로그램 종료1강에서 시스템 호출을 실행하는 방법을 성공적으로 배웠다면 이제 커널에서 가장 중요한 시스템 호출 중 하나인 sys_exit에 대해 배워야 한다. ‘Hello, world!’ 프로그램이 실행된 후 어떻게 세그멘테이션 오류가 발생했는지 기억하시나요? 컴퓨터 프로그램은 메모리에 로드되어 섹션(또는 세그먼트)으로 나뉘어져 있는 긴 명령어 조각으로 생각할 수 있다. 이 일반적인 메모리 풀은 모든 프로그램 간의 공유되며 변수, 명령어, 다른 프로그램 또는 실제로 무엇이든 저장하는 데 사용할 수 있다. 각 세그먼트에는 해당 섹션에 저장된 정보를 나중에 찾을 수 있도록 주소가 지정된다. 메모리에 로드된 프로그램을 실행하려면 글로벌 레이블 _start: 를 사용하여 운영 체제에 메모리에서 프로그램을..
어셈블리 언어는 베어본 언어다. 프로그래머가 실제 하드웨어 위에 있는 유일한 인터페이스는 커널 자체뿐이다. 어셈블리에서 유용한 프로그램을 빌드하려면 커널에서 제공하는 리눅스 시스템 호출을 사용해야함. 이러한 시스템 호출은 키보드에서 입력을 읽고 화면에 출력을 쓰는 등의 기능을 제공하기 위해 운영 체제에 내장된 라이브러리이다. 시스템 호출을 호출하면 커널은 프로그램 실행을 일시 중단한다. 그 다음 하드웨어에서 요청한 작업을 수행하는데 필요한 드라이버에 연결한 다음 프로그램 제어권을 다시 돌려준다. 커널은 드라이버를 사용하여 하드웨어를 구동하기 때문에 드라이버를 드라이버라고 부른다. 어셈블리에서 실행하려는 함수 번호(작업 코드 OPCODE)로 EAX를 로드하고 나머지 레지스터를 시스템 호출에 전달할 인수로 ..