Q1. 어셈블리어 코드 => C 코드로 변환하시오
어셈블리어 코드
section .data
number1 dd 10
number2 dd 20
result dd 0
section .text
global _start
_start:
mov eax, [number1] ; number1을 eax 레지스터에 로드
add eax, [number2] ; number2를 더함
mov [result], eax ; 결과를 result 변수에 저장
; 프로그램 종료 시스템 콜
mov eax, 1 ; 시스템 콜 번호: 프로그램 종료
xor ebx, ebx ; 종료 코드 0
int 0x80 ; 시스템 콜
section .bss
C언어 코드
#include <stdio.h>
int main() {
int number1 = 10;
int number2 = 20;
int result;
result = number1 + number2;
printf("Result: %d\n", result);
return 0;
}
Q2. 이 코드가 race condition이 발생할 수 있는가? 발생한다면 왜 그런지 작성하시오
Race condition : 다중 스레드 또는 프로세스가 공유 자원(예: 변수 또는 메모리)을 동시에 업데이트하려고 할 때 발생하는 문제
section .data
shared_data dd 0
section .text
global main
main:
; 스레드 1
mov eax, 1
mov [shared_data], eax ; 공유 데이터에 1을 저장
; 스레드 2
mov ebx, 2
mov [shared_data], ebx ; 공유 데이터에 2를 저장
; 스레드 1
mov eax, [shared_data] ; 공유 데이터를 읽음
add eax, 3
mov [shared_data], eax ; 공유 데이터에 4를 저장
; 스레드 2
mov ebx, [shared_data] ; 공유 데이터를 읽음
sub ebx, 1
mov [shared_data], ebx ; 공유 데이터에 1을 저장
; 스레드 1
mov eax, [shared_data] ; 공유 데이터를 읽음
; 스레드 2
mov ebx, [shared_data] ; 공유 데이터를 읽음
; 결과를 출력하거나 다른 작업을 수행
이 코드에서, 두 개의 스레드가 shared_data라는 공유 데이터에 동시에 접근하고 수정하려고 합니다.
이렇게 하면 race condition이 발생할 수 있습니다.
Race condition을 피하려면 어셈블리어 또는 다른 언어에서 세마포어와 같은 동기화 도구를 사용하여 공유 데이터에 대한 동시 접근을 조절해야 합니다
Q3. zombie process, orphan process 개념, 해결법
좀비 프로세스 (zombie process)
정의 : 자식 프로세스가 부모 프로세스보다 먼저 종료되는 경우
해결법 : 부모 프로세스가 죽지 않으면 자식 프로세스를 kill 해도 죽지 않기 때문에 부모 프로세스를 찾아서 kill 한다
고아 프로세스 (orphan process)
정의 : 부모 프로세스가 자식 프로세스보다 먼저 종료되는 경우
해결법 : 자식 프로세스의 새로운 부모 프로세스를 init 프로세스로 지정한다
https://dkswnkk.tistory.com/491
Q4. message queue 코드 보고 잘 돌아가는지 check
메시지 큐 : 프로세스 or 프로그램 인스턴스가 데이터를 서로 교환할 때 사용하는 통신 방법
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <mqueue.h>
int main() {
mqd_t mq; // 메시지 큐 디스크립터
struct mq_attr attr;
char buffer[1024];
int bytesRead;
// 메시지 큐 속성 설정
attr.mq_flags = 0;
attr.mq_maxmsg = 10; // 최대 메시지 수
attr.mq_msgsize = 1024; // 각 메시지의 최대 크기
attr.mq_curmsgs = 0; // 현재 메시지 수
// 메시지 큐 생성 (생산자와 소비자가 동일한 큐에 액세스)
mq = mq_open("/my_queue", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr);
if (mq == (mqd_t)-1) {
perror("mq_open");
exit(1);
}
// 메시지 전송
char *message = "Hello, World!";
if (mq_send(mq, message, strlen(message), 0) == -1) {
perror("mq_send");
exit(1);
}
// 메시지 수신
bytesRead = mq_receive(mq, buffer, sizeof(buffer), NULL);
if (bytesRead == -1) {
perror("mq_receive");
exit(1);
}
// 수신한 메시지 출력
buffer[bytesRead] = '\0';
printf("Received: %s\n", buffer);
// 메시지 큐 닫기
if (mq_close(mq) == -1) {
perror("mq_close");
exit(1);
}
// 메시지 큐 삭제
if (mq_unlink("/my_queue") == -1) {
perror("mq_unlink");
exit(1);
}
return 0;
}
이 코드는 메시지 큐를 생성하고 메시지를 보내고 받는 간단한 예제입니다.
프로듀서는 "Hello, World!"라는 메시지를 큐에 보내고, 컨슈머는 큐에서 메시지를 받아 출력합니다.
이 코드는 POSIX 메시지 큐 API를 사용하며, 프로듀서와 컨슈머가 동일한 큐를 공유합니다.
Q5. 어셈블리어 instruction을 보고, 실행 후 메모리와 레지스터 값 적기
MOV AX, 10 ; AX 레지스터에 10을 저장
MOV BX, 20 ; BX 레지스터에 20을 저장
ADD AX, BX ; AX = AX + BX
예상 결과:
메모리:
- 메모리는 직접적으로 이 코드에서 변경되지 않았으므로 변화가 없습니다.
레지스터:
- AX: 30 (10 + 20)
- BX: 20
MOV AX, 42 ; AX 레지스터에 42를 저장
MOV [1000], AX ; 메모리 주소 1000에 AX 레지스터의 값을 저장
예상 결과:
메모리:
- 메모리 주소 1000: 42 (AX 레지스터의 값)
레지스터:
- AX: 42
Q6. 메모리 주소와 값을 적은 표를 보고 어셈블리어 명령을 수행하시오
주소 값
1000 42
1004 30
1008 0
section .data
message db "결과: ", 0
section .bss
result resb 4
section .text
global _start
_start:
; 메모리 주소 1000에서 값 42를 레지스터에 로드
mov eax, [1000]
; 메모리 주소 1004에서 값 30을 추가
add eax, [1004]
; 결과를 메모리 주소 1008에 저장
mov [1008], eax
; 결과를 화면에 출력
mov eax, 4
mov ebx, 1
mov ecx, message
mov edx, 8
int 0x80
; 결과 값을 출력
mov eax, 4
mov ebx, 1
mov ecx, result
mov edx, 4
int 0x80
; 프로그램 종료
mov eax, 1
int 0x80
이 코드는 메모리 주소 1000에서 42를 읽고, 메모리 주소 1004에서 30을 읽어서 더한 다음, 결과를 메모리 주소 1008에 저장하고, 결과를 화면에 출력하는 간단한 어셈블리어 프로그램입니다.
어셈블리어 명령을 수행하라 = 컴파일한 값이 무엇이냐?
Q7. 프로그램 코드의 실행 결과를 작성하시오
section .data
num1 dd 10
num2 dd 20
result dd 0
section .text
global _start
_start:
; num1과 num2의 값을 더하여 result에 저장
mov eax, [num1] ; num1의 값을 레지스터 eax에 로드
add eax, [num2] ; num2의 값을 레지스터 eax에 더함
mov [result], eax ; 결과를 result 변수에 저장
; 결과를 출력하기 위해 레지스터 eax에 result 값 로드
mov eax, [result]
; 결과를 출력하는 시스템 콜 호출
mov ebx, 1 ; 파일 디스크립터(표준 출력)를 ebx 레지스터에 저장
mov ecx, eax ; 출력할 메시지의 주소를 ecx 레지스터에 저장
mov edx, 4 ; 출력할 바이트 수를 edx 레지스터에 저장
mov eax, 4 ; 시스템 콜 번호 (sys_write)를 eax 레지스터에 저장
int 0x80 ; 시스템 콜 실행
; 프로그램 종료를 위한 시스템 콜 호출
mov eax, 1 ; 시스템 콜 번호 (sys_exit)를 eax 레지스터에 저장
xor ebx, ebx ; 종료 코드를 ebx 레지스터에 저장 (0은 정상 종료를 의미)
int 0x80 ; 시스템 콜 실행
결과값 : 30 [10 + 20]
Q8. 코드의 문제점이 있다면 수정할 방법을 작성하시오
'시스템 프로그래밍 > 대학교 강의 정리' 카테고리의 다른 글
[시스템 프로그래밍] 기말 정리 (0) | 2023.12.10 |
---|---|
[시스템 프로그래밍] 어셈블리어 (0) | 2023.10.15 |
시스템 프로그래밍 (0) | 2023.09.03 |
오리엔테이션 (0) | 2023.08.28 |