주제 1
다음 프로그램을 컴파일하고 링크한 후 디버그로 로드하고 추적한 후 질문에 답하세요.
assume cs:code, ds:data, ss:stack
data segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h ; 占16字节
data ends
stack segment
dw 1,2,3,4,5,6,7,8 ; 占16字节
stack ends
code segment
start: mov ax, stack ; 获取栈段
mov ss, ax ; 设置栈段
mov sp, 16 ; 设置栈顶 ss:sp
mov ax, data
mov ds, ax ; ds 指向 data 段
push ds:[0]
push ds:[2]
pop ds:[2]
pop ds:[0]
mov ax, 4c00h
int 21h
code ends
end start
- CPU가 프로그램을 실행합니다. 프로그램이 반환되기 전에 데이터 세그먼트에 얼마나 많은 데이터가 있습니까?
대답: 데이터는 변경되지 않았습니다. 선입선출 순서가 유지됩니다. - CPU는 프로그램이 반환되기 전에 프로그램을 실행합니다. cs= 076E , ss= 076D , ds= 076C .
- 프로그램이 로드된 후 코드 세그먼트의 세그먼트 주소는 X이고 데이터 세그먼트의 세그먼트 주소는 X- 2 이며 스택 세그먼트의 세그먼트 주소는 X-1 입니다 .
주제 2
다음 프로그램을 컴파일하고 링크한 후 디버그로 로드하고 추적한 후 질문에 답하세요.
assume cs:code, ds:data, ss:stack
data segment
dw 0123h,0456h
data ends
stack segment
dw 1,2
stack ends
code segment
start: mov ax, stack ; 获取栈段
mov ss, ax ; 设置栈段
mov sp, 16 ; 设置栈顶 ss:sp
mov ax, data
mov ds, ax ; ds 指向 data 段
push ds:[0]
push ds:[2]
pop ds:[2]
pop ds:[0]
mov ax, 4c00h
int 21h
code ends
end start
- CPU가 프로그램을 실행합니다. 프로그램이 반환되기 전에 데이터 세그먼트에 얼마나 많은 데이터가 있습니까?
대답: 데이터는 변경되지 않았습니다. 선입선출 순서가 유지됩니다. - CPU는 프로그램이 반환되기 전에 프로그램을 실행합니다. cs= 076E , ss= 076D , ds= 076C .
- 프로그램이 로드된 후 코드 세그먼트의 세그먼트 주소는 X이고 데이터 세그먼트의 세그먼트 주소는 X- 2 이며 스택 세그먼트의 세그먼트 주소는 X-1 입니다 .
- 다음과 같이 정의된 섹션의 경우: 섹션의 데이터가 N 바이트를 차지하는 경우 프로그램이 로드된 후 섹션이 실제로 차지하는 공간은 바이트입니다. 인터넷에서 다른 사람의 공식을 봤는데 정확히 16의 배수일 때 공식이 관찰된 효과와 일치하지 않습니다.
n % 16 ? n + (16 - n % 16) : n
( N/16+1) * 16
name segment
...
name ends
프로그램이 로드된 후 CX=0042가 질문 1 과 동일하다는 점을 확인하세요 . 4바이트만 선언되었음에도 불구하고 시스템은 여전히 16바이트에 따라 메모리를 할당하는 것을 볼 수 있습니다.
볼 수 数据段
있고 될 수 栈段
있습니다 16字节
. 076C:0020代码段
부터 . 관찰을 통해 추측의 결과를 살펴보세요.
[...Array(9527).keys()].map(n => `${
n} = ${
n % 16 ? n + (16 - n % 16) : n}`)
주제 3
다음 프로그램을 컴파일하고 링크한 후 디버그로 로드하고 추적한 후 질문에 답하세요.
- CPU가 프로그램을 실행합니다. 프로그램이 반환되기 전에 데이터 세그먼트에 얼마나 많은 데이터가 있습니까?
대답: 데이터는 변경되지 않았습니다. 선입선출 순서가 유지됩니다. - CPU는 프로그램이 반환되기 전에 프로그램을 실행합니다. cs= 076C , ss= 0770 , ds= 076F .
- 프로그램이 로드된 후 코드 세그먼트의 세그먼트 주소는 X이고 데이터 세그먼트의 세그먼트 주소는 = X+3 이며 스택 세그먼트의 세그먼트 주소는 X+4 입니다 .
주제 4
질문 (1), (2) 및 (3)의 마지막 의사 명령어 "end start"가 "end"로 변경된 경우(즉, 프로그램의 진입점이 지정되지 않은 경우), 어떤 프로그램이 계속해서 실행될 수 있습니까? 올바르게 실행되었나요? 이유를 설명해 주세요.
답: 문제 3의 코드는 코드 세그먼트가 프로그램 시작 부분에 있기 때문에 정상적으로 실행될 수 있습니다. CS:IP는 명령의 첫 번째 줄을 가리킵니다.
주제 5
프로그램은 다음과 같이 코드 세그먼트에 코드를 작성하고, a
세그먼트와 b
세그먼트에 차례로 데이터를 추가하고, 그 결과를 c
세그먼트에 저장합니다.
assume cs:code
a segment
db 1, 2, 3, 4, 5, 6, 7, 8 ; 占16字节
a ends
b segment
db 1, 2, 3, 4, 5, 6, 7, 8 ; 占16字节
b ends
d segment
db 0, 0, 0, 0, 0, 0, 0, 0 ; 占16字节
d ends
code segment
start: mov ax, a
mov ds, ax
mov bx, 0 ; i = 0
mov cx, 8 ; len = 8
s: mov al, ds:[bx]
add al, ds:[bx+16] ; 寄存器不够用,用偏移量来定位
mov ds:[bx+16+16], al ; 寄存器不够用,用偏移量来定位
inc bx ; i++
loop s ; i < len 循环
mov ax, 4c00h
int 21h
code ends
end start
c segment
컴파일되지 않아서 다음으로 대체했습니다.d
- 프로그램이 로드된 후 CS:IP가 076F:0 을 가리키는 것을 볼 수 있습니다.
[bx+16+16]
이러한 글쓰기 방법은 7장에서 자세히 소개될 것이다.
주제 6
프로그램은 다음과 같습니다. 코드 섹션에 코드를 작성하고 push 명령을 사용하여 a 섹션의 처음 8개 글꼴 데이터를 b 섹션에 역순으로 저장합니다.
assume cs:code
a segment ; CS-3
dw 1,2,3,4,5,6,7,8,9,0ah,0bh,0ch,0dh,0eh,0fh,0ffh ; 占32字节
a ends
b segment ; CS-1
dw 0,0,0,0,0,0,0,0 ; 占16字节
b ends
code segment
start: mov ax, a
mov ds, ax
mov ax, b
mov ss, ax
mov sp, 10h
; 下面实现循环处理
mov bx, 0 ; i = 0
mov cx, 8 ; len = 8
s: push [bx] ; a 中取出第一个,放到 b末尾。压栈是从底往上走的
add bx, 2 ; i = i+2 字类型占两字节
loop s ; i < len 循环
mov ax, 4c00h
int 21h
code ends
end start
요약하다
- 시스템은 16바이트부터 메모리를 할당합니다.
- 세그먼트를 정의하면 콘텐츠 공간이 선언됩니다. 한 가지.
- 세그먼트의 정의 순서와 크기를 알면 오프셋을 통해 각 세그먼트의 위치를 계산할 수 있습니다.