어셈블리 프로그래밍 13(12-02, 13-01)
=== Windows API Assembly & Redirection ===
Windows API
- API (Application Programming Interface)
- A computing interface which defines interactions between multiple software intermediaries(1).
- A collection of types, constants, and functions that provide a way to directly manipulate objects through programming.
- Microsoft Win32 API에는 어셈블리용 interface도 제공.
- SDK (Software Development Kit)
- A collection of tools, libraries, sample code, and documentation that helps programmers create applications.
- 프로그래밍에 많이 쓰이는 용어이므로 API와 SDK와의 차이를 알아보도록 하자(2).
(1) https://en.wikipedia.org/wiki/Application_programming_interface
(2) https://hyesunzzang.tistory.com/90 Win32 Console Programming
- API (Application Programming Interface)
- A computing interface which defines interactions between multiple software intermediaries(1).
- A collection of types, constants, and functions that provide a way to directly manipulate objects through programming.
- Microsoft Win32 API에는 어셈블리용 interface도 제공.
- SDK (Software Development Kit)
- A collection of tools, libraries, sample code, and documentation that helps programmers create applications.
- 프로그래밍에 많이 쓰이는 용어이므로 API와 SDK와의 차이를 알아보도록 하자(2).
(1) https://en.wikipedia.org/wiki/Application_programming_interface
(2) https://hyesunzzang.tistory.com/90 Win32 Console Programming
API는 여러가지 소프트웨어와 대화하고 통신한다. types, constant, function을 제공해서 다른 object들을 프로그래밍하는데 도움이 된다.
Win32API는 어셈블리용 interface도 제공한다.
SDK는 유저가 프로그래밍을 쉽게 할 수 있도록 하는데 목표를 둔다.
Win32 Console Programming
- Windows Console
- MS 윈도우에서 텍스트 기반 사용자 인터페이스와 콘솔 애플리케이션을 위한 윈도우 API 기반 하부 구조(1).
- Win32 Console Programs
Run in Protected mode and MS-DOS
Standard text-based input and output
Linker option : /SUBSYSTEM:CONSOLE
The console input buffer contains a queue of input records, each containing data about an input event.
The console screen buffer is a 2-d array of character and color data that affects the appearance of text in the console window.
(1) https://ko.wikipedia.org/wiki/윈도우_콘솔
Win32 Console은 명령프롬프트를 이야기 한다. 그래서 텍스트 기반 사용자들을 위해 API function들을 제공한다.
항상 input buffer에서 입력된 내용들이 저장된다. CPU I/O로 전달된다. 출력도 screen buffer에 저장되고 나오게 된다. screen buffer은 2차원 배열이라 char, color등을 저장할 수 있다.
API Functions for Win32 Console Program
- API Functions for Win32 Console Program
Irvine library 함수들은 이들 API 함수들로 작성되어 있다.
Redirection은 안되고 오직 stdin, stdout, stderr 만 가능.
Can read/write in either Unicode (wide-character) or ANSI mode.
Irvine library 함수들은 이들 API 함수들로 작성되어 있다.
Redirection은 안되고 오직 stdin, stdout, stderr 만 가능.
Can read/write in either Unicode (wide-character) or ANSI mode.
Irvine도 API함수들로 그 내부가 구성되어 있다.
Redirection이란 scanf는 stdin, printf는 stdout으로 연결되어 있다. 이것을 file로 입력 출력을 결정하고 싶을때 '<', '>'을 사용해서 사용할 수 있다. 그런데 Win32 콘솔용 API 함수는 redirection이 안된다.
- Standard Console Handles
A handle is an unsigned 32-bit integer. The following MS-Windows constants are predefined:
STD_INPUT_HANDLE : standard input
STD_OUTPUT_HANDLE : standard output
STD_ERROR_HANDLE : standard error output
handle이라는 것은 file pointer이라고 생각하면 된다. handle이 사전에 정의되어 있다.
GetStdHandle
Returns a handle in EAX to a console stream
Prototype:
The handle type is either STD_INPUT_HANDLE, STD_OUTPUT_HANDLE or STD_ERROR_HANDLE.
nStdHandle에는 STD_INPUT_HANDLE 혹은 STD_OUTPUT_HANDLE을 넣으면 된다. 그러면 filepointer을 EAX에 넣어서 반환해준다. 그걸 받아서 HANDLE 타입 변수에 넣어주면된다.
- ReadConsole : Console Input
읽고싶다고하면 ReadConsole을 사용하면 된다. 처음에는 handle, Buffer, maxBytes, 실재로 읽은 char 수(pBytesRead)
- WriteConsole : Console Output
handle, pBUffer 출력buf, bufsize, pCount 실재로 write한 char
Example : String Echo
중간에 보면 ADDR Msg라고 적히어 있는데 OFFSET 대신에 이렇게 적으라고 적히어 있어서 일부러 이렇게 작성했다. 이것들은 스택에서 0부터 시작해서 stdInHandle까지 들어가게 된다.
여기에는 CRLF가 있어서 bytesRead에서 2를 뺐다.
API Functions for File Manipulation(1,2)
API Functions for File Manipulation
- Console 프로그래밍을 위한 ReadConsole, WriteConsole 등의 함수는 redirection이 되지 않는다.
- MS Win32 API에서는 File I/O 함수들을 제공하고 있다.
- 이들 함수들은 redirection이 가능하다
- Handle로 STD_INPUT_HANDLE, STD_OUTPUT_HANDLE 등을 사용하면 된다.
- 이는 fscanf, fprintf에서 file pointer로 stdin, stdout 등을 사용하면 console IO가 가능한 것과 마찬가지이다.
- Handle로 STD_INPUT_HANDLE, STD_OUTPUT_HANDLE 등을 사용하면 된다.
- 이는 fscanf, fprintf에서 file pointer로 stdin, stdout 등을 사용하면 console IO가 가능한 것과 마찬가지이다.
STD_INPUT_HANDLE, STD_OUTPUT_HANDLE 을 사용하면 consol I/O가 된다.
(1) See 11.1.
(2) Also See MSDN document for detailed description of each argument.
CreateFile
- Either creates a new file or opens an existing file.
- If successful, returns a handle in EAX to the open file; otherwise, it returns a special constant named INVALID_HANDLE_VALUE.
파일을 생성하겠다고 하면 CreatFile을 호출할 수 있다.
Close File
CreateFile Examples
- Open an existing file for reading(handle will be in eax)
이미 있는 file을 open하겠다.
filename을 주어야 한다.
desiredAccess는 GENERIC_READ라고 이미 정의된 identifier을 사용하면 된다.
DO_NOT_SHARE은 딴 프로세스와 share하는지를 물어보는거 가다.
file creation option은 OPEN_EXISTING 이미 있는 file을 open해라
FILE_ATTRIBUTE_NORMAL
- Open an existing file for writing
GENERIC_WRITE로 바뀐것을 제외하고 특별한 점은 없다.
- Creates a new file with normal attributes, erasing any existing file by the same name:
CREATE_ALWAYS만 다르다. 만약 기존에 file이 있었으면 file을 삭제하고 다시생성
ReadFile
console이면 엔터치면 끝나지만 nBufsize가 80일때 파일을 읽는다면 무조건 80글자를 읽게 된다.
WriteFile
pOverlapped는 NULL 집어넣자
SetFilePointer
-
Moves the position pointer of an open file.
-
May be used to append data to a file, and to perform random-access record processing:
원하는 위치로 이동, random access가능해진다.
nDistanceLo, pDistanceHi는 moveMethod를 시작점으로 두어서 이동이 가능해진다. -
Example: Move to the end of a file
예를 들어 위와 같이 한다면 FILE_END로 가서 안움직이겠다는 의미이다. 즉 FILE_END부터 작성하겠다는 의미가 된다.
=== Recursion ===
Recursion
Recursive Function
- 두 가지 형태가 존재한다.
- A procedure calls itself
- Procedure A calls procedure B, which in turn calls A.
A가 A를 호출하는 방법, A<->B으로 호출하는 방법
- Recursive Procedure의 구조
- 함수 초기에 종료 조건 체크가 반드시 있어야 한다.
- 자기 자신인 함수는 한 번 이상 호출해도 무방하다.
Recursive Function
- 두 가지 형태가 존재한다.
- A procedure calls itself
- Procedure A calls procedure B, which in turn calls A.
A가 A를 호출하는 방법, A<->B으로 호출하는 방법
- Recursive Procedure의 구조
- 함수 초기에 종료 조건 체크가 반드시 있어야 한다.
- 자기 자신인 함수는 한 번 이상 호출해도 무방하다.
Recursion은 반드시 끝낼조건이 있어야 한다.
Recursively Calculating a Sum
-
Problem to be solved : calculate 1 + 2 + … + N.
-
S(N) = 1 + 2 + … + N이라고 하면 S(N)은 다음과 같은 recurrent equation으로 나타낼 수 있다.
-
S(N)을 함수라고 하면, 수학적 귀납법(mathematical induction)으로 1 + 2 + … + N을 정확하게 구한 다는 것을 보일 수 있다.
-
The behavior of most recursive functions can be proved by mathematical induction.
-
CalcSum recursively calculates the sum of an array of integers.
- Receives: ECX = count. Returns: EAX = sum.
- Receives: ECX = count. Returns: EAX = sum.
Factorial Calculation
- This function below calculates the factorial of integer n.
- A new value of n is saved in each stack frame:
- Assembly Procedure
처음에 n을 push하고 진입한다고 가정하고 코드를 보자
매 호출마다 stack을 12byte를 사용한다.
Boolean List Generation
- 크기가 N인 Boolean List는 N 개의 Boolean values F/T (또는 0/1) 조합을 의미한다.
- 이러한 모든 조합을 recursion을 사용하여 생성해 보자.
- 작성할 프로그램은 아래 좌측의 입력에 대해 우측과 같이 출력한다.
모든 T/F 조합을 출력하라 input n에 대해서 total 2^n combination이다.
-
함수 설계
T/F list를 저장하기 위한 배열을 B[0…N-1]이라고 하자.
함수를 호출하면 다음과 같은 과정으로 T, F 값을 배열 B에 저장한다.
이를 일반화 하여, i = 0 : k-1에 대해 B[i]의 T/F 값이 정해졌다면, B[k : N-1]에 대해 모든 가능한 T/F 리스트를 다음과 같이 구할 수 있다.
그래서 하나를 각각 넣고 남은 것에 대해서 함수를 호출하면 된다. 이때는 어쩔 수 없이 함수내에 출력을 호출해야 한다. 그러지 않으면 아예 출력을 못한다. -
따라서, recursion 함수의 입력 parameter는 배열 B와 현재 어디 부터 T/F 값을 모두 구할지를 나타내는 k가 있어야 한다.
-
함수는 k = 0 부터 순서대로 B에 T/F 값을 배정할 것이다.
-
따라서, k = N이면 B[0 : N-1]까지 T/F 값이 결정된 것이므로 Boolean list 하나를 구한 것이며, 이를 출력한다
void BooleanList(int N, int k, int B[ ]) {
if (k == N) {
// T/F 리스트 하나를 구했다.
B[0 : N-1] 값을 출력; // 또는 B를 이용한 어떤 필요한
// 다른 일을 수행할 수도 있다.
return;
}
B[k] = 'F'; // T/F 대신 필요하다면 다른
BooleanList(N, k+1, B); // 값을 사용해도 된다(예: 1/0)
B[k] = 'T';
BooleanList(N, k+1, B);
return;
}
- 프로그램 작성(INVOKE를 사용하지 않는 경우)
call Boolean List 호출방법 != INVOKE PROG
WriteFile 함수를 사용하겠다. 고해서 handle 이 들어가 있다.
할때 B_Written을 미리 작성해놓으면 나중에 편하게 사용가능해진다.
H가 handle, B가 buffer, ecx는 갯수, ADDR B_Written__은 실재 쓴 갯수
ret 16을 쓴 이유는 16개를 뺏기 때문.
- 호출 프로그램(INVOKE를 사용하지 않는 경우)
stdin, stdout을 쓰겠다는 것을 미리 정의해 놓아서 나중에 Redirection할 수 있는 경우를 대비한다.
프로그램 작성(INVOKE를 사용하는 경우)
- 호출 프로그램(INVOKE를 사용하는 경우)
Multimodule Programs
Multimodule Programs
- A multimodule program is a program whose source code has been divided up into separate ASM files.
- Each ASM file(module) is assembled into a separate OBJ file.
- All OBJ files belonging to the same program are linked using the link utility into a single EXE file.
- This process is called static linking.
- Advantages
- Large programs are easier to write, maintain, and debug when divided into separate source code modules.
- When changing a line of code, only its enclosing module needs to be assembled again. Linking assembled modules requires little time.
- Large programs are easier to write, maintain, and debug when divided into separate source code modules.
- When changing a line of code, only its enclosing module needs to be assembled again. Linking assembled modules requires little time.
쉽게 이야기 해서 필요한 것만 모아서 컴파일 하겠다는 이야기이다.
Creating a Multimodule Program
- Here are some basic steps to follow when creating a multimodule program:
- Create the main module.
- Create a separate source code module for each procedure or set of related procedures.
- Create an include file that contains procedure prototypes for external procedures (ones that are called between modules).
- Use the INCLUDE directive to make your procedure prototypes available to each module.
소스 코드를 모두 분리할 수 있다.
prototype만 모아서 ~.inc 파일을 만들고 이를 추가할 수 있다.
Example: ArraySum Program
CSE3030 어셈블리 프로그래밍 24
Summation
Program (main)
Clrscr PromptForIntegers ArraySum DisplaySum
WriteString ReadInt WriteString WriteInt WriteInt
Each of the four
white rectangles will
become a module.
Enter a signed integer: -25
Enter a signed integer: 36
Enter a signed integer: 42
The sum of the integers is: +53
sample
program
in/outINCLUDE File
The sum.inc file contains prototypes for external functions
that are not in the Irvine32 library
CSE3030 어셈블리 프로그래밍 25
INCLUDE Irvine32.inc
PromptForIntegers PROTO,
ptrPrompt:PTR BYTE, ; prompt string
ptrArray:PTR DWORD, ; points to the array
arraySize:DWORD ; size of the array
ArraySum PROTO,
ptrArray:PTR DWORD, ; points to the array
count:DWORD ; size of the array
DisplaySum PROTO,
ptrPrompt:PTR BYTE, ; prompt string
theSum:DWORD ; sum of the arrayIndividual Modules
Main
CSE3030 어셈블리 프로그래밍 26
TITLE Integer Summation Program (Sum_main.asm)
INCLUDE sum.inc
; modify Count to change the size of the array:
Count = 3
.data
prompt1 BYTE "Enter a signed integer: ",0
prompt2 BYTE "The sum of the integers is: ",0
array DWORD Count DUP(?)
sum DWORD ?main (계속)
CSE3030 어셈블리 프로그래밍 27
.code
main PROC
call Clrscr
INVOKE PromptForIntegers, ; input the array
ADDR prompt1,
ADDR array,
Count
INVOKE ArraySum, ; sum the array
ADDR array, ; (returns sum in EAX)
Count
mov sum,eax ; save the sum
INVOKE DisplaySum, ; display the sum
ADDR prompt2,
sum
call Crlf
INVOKE ExitProcess,0
main ENDP
END mainProcedures
CSE3030 어셈블리 프로그래밍 28
TITLE Prompt For Integers (_prompt.asm)
INCLUDE sum.inc
.code
PromptForIntegers PROC,
ptrPrompt:PTR BYTE, ; prompt string
ptrArray:PTR DWORD, ; pointer to array
arraySize:DWORD ; size of the array
; Prompts the user for an array of integers and
fills
; the array with the user's input.
; Returns: nothing
pushad ; save all registers
mov ecx,arraySize
cmp ecx,0 ; array size <= 0?
jle L2 ; yes: quitProcedures
CSE3030 어셈블리 프로그래밍 29
mov edx,ptrPrompt ; address of the prompt
mov esi,ptrArray
L1: call WriteString ; display string
call ReadInt ; read integer into EAX
call Crlf ; go to next output line
mov [esi],eax ; store in array
add esi,4 ; next integer
loop L1
L2: popad ; restore all registers
ret
PromptForIntegers ENDP
ENDProcedures
CSE3030 어셈블리 프로그래밍 30
TITLE ArraySum Procedure (_arrysum.asm)
INCLUDE sum.inc
.code
;-----------------------------------------------
ArraySum PROC,
ptrArray:PTR DWORD, ; pointer to array
arraySize:DWORD ; size of array
; Calculates the sum of an array of 32-bit
integers.
; Returns: EAX = sum
push ecx ; don't push EAX
push esi
mov eax,0 ; set the sum to zero
mov esi,ptrArray
mov ecx,arraySize
cmp ecx,0 ; array size <= 0?
jle AS2 ; yes: quitProcedures
CSE3030 어셈블리 프로그래밍 31
AS1:
add eax,[esi] ; add each integer to sum
add esi,4 ; point to next integer
loop AS1 ; repeat for array size
AS2:
pop esi
pop ecx ; return sum in EAX
ret
ArraySum ENDP
ENDProcedures
CSE3030 어셈블리 프로그래밍 32
TITLE DisplaySum Procedure (_display.asm)
INCLUDE Sum.inc
.code
;-----------------------------------------------
DisplaySum PROC,
ptrPrompt:PTR BYTE, ; prompt string
theSum:DWORD ; the array sum
; Displays the sum on the console.
; Returns: nothing
push eax
push edx
mov edx,ptrPrompt ; pointer to prompt
call WriteString
mov eax,theSum
call WriteInt ; display EAX
call Crlf
pop edx
pop eax
ret
DisplaySum ENDP
END Assemble and Link
In Visual Studio : add files to the project, and build them.
CSE3030 어셈블리 프로그래밍 33VS2017용 개발자 명령 프롬프트에서
아래와 같은 .bat 파일을 만들어 수행
CSE3030 어셈블리 프로그래밍 34
ml /c /nologo /Zi /I "C:\Irvine" /Fl /W3 ^
/errorReport:prompt /Ta ^
multi_sum_main.asm multi_sum_prompt.asm ^
multi_sum_sum.asm multi_sum_display.asm
SET LIB=c:\Irvine
link multi_sum_main.obj multi_sum_prompt.obj ^
multi_sum_sum.obj multi_sum_display.obj ^
Irvine32.lib Kernel32.lib User32.lib /subsystem:consol
Author And Source
이 문제에 관하여(어셈블리 프로그래밍 13(12-02, 13-01)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@tonyhan18/어셈블리-프로그래밍-1312-02-13-01저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)