[Thông báo] Chuyển diễn đàn


Diễn đàn về free Code sẽ chuyển sang ICT2.net







You are not connected. Please login or register

Xem chủ đề cũ hơn Xem chủ đề mới hơn Go down  Thông điệp [Trang 1 trong tổng số 1 trang]

1default Co it dap an cau hoi VXL-VDK on 30/9/2011, 9:44 pm

THPTDH


Moderator
Moderator
Loading
Khong biet co chuan xac khong.AE dem ve test roi cho y kien (cai nay suu tap dc)

http://www.mediafire.com/?623pddqyy0ympmm

2default Re: Co it dap an cau hoi VXL-VDK on 1/10/2011, 10:02 am

forever


Moderator
Moderator
http://vn.360plus.yahoo.com/foryou_forme_90
Loading
thanks nhe !

3default Re: Co it dap an cau hoi VXL-VDK on 1/10/2011, 10:53 am

thanh_nguyenduc


Super Moderator
Super Moderator
Loading
ok. problem....
try more. you're welcome Very Happy

4default Re: Co it dap an cau hoi VXL-VDK on 3/10/2011, 9:32 pm

THPTDH


Moderator
Moderator
Loading
thanh_nguyenduc đã viết:ok. problem....
try more. you're welcome Very Happy
:207: :207: :207:

5default Re: Co it dap an cau hoi VXL-VDK on 9/10/2011, 9:32 am

buiducdungtnut


♥ Bé Bỏng ♥
♥ Bé Bỏng ♥
Loading
oh hay, kai nhom 2 lam vxl-vdk ko thay pm j ka the,

6default Re: Co it dap an cau hoi VXL-VDK on 9/10/2011, 2:40 pm

ladykiller


♥ Chém gió sơ cấp ♥
♥ Chém gió sơ cấp ♥
Loading
ngon

7default Re: Co it dap an cau hoi VXL-VDK on 11/10/2011, 1:19 pm

trandieudvt01


♥ Chém gió sơ cấp ♥
♥ Chém gió sơ cấp ♥
Loading
VXL-VDK kỳ chính thấy học cả bài tập phần mảng, học hè phần mảng bọn tôi chỉ học khai báo thôi. :12212: :12212:

8default Re: Co it dap an cau hoi VXL-VDK on 11/10/2011, 10:02 pm

THPTDH


Moderator
Moderator
Loading
biết ông được tích 4 rồi.Có kinh nghiệm chia sẻ anh em với

9default Re: Co it dap an cau hoi VXL-VDK on 13/10/2011, 1:18 am

trandieudvt01


♥ Chém gió sơ cấp ♥
♥ Chém gió sơ cấp ♥
Loading
có vài dạng BT về mảng nhưng account chưa đủ 7 ngày nên ko post link được. mình paste tạm ra đây nhé.

Chương 7: Mảng và các chế độ địa chỉ

Trong chương này chúng ta sẽ đề cập đến mảng một chiều và các kỹ thuật xử lý mảng trong Assembly . Phần còn lại củachương này sẽ trình bày các chế độ địa chỉ.
7.1 Mảng một chiều
Mảng một chiều là một danh sách các phần tử cùng loại và có trật tự. Có trật tự có nghĩa là có phần tử thứ nhất, phần tử thứ hai, phần tử thứ ba ... Trong toán học, nếu A là một mảng thì các phần tử của mảng được định nghĩa làA[1}, A[2] , A[3] ... Hình vẽ là dưới đây là mảng A có 6 phần tử .



Trong chương 1 chúng ta đã dùng toán tử giả DB và DW để khai báo mảng byte và mảng từ . Ví dụ , một chuổi 5 ký tự có tên là MSG MSG DB 'abcde' hoặc một mảng từ W gồm 6 số nguyên mà giá trị ban đâù của chúng là 10,20,30,40.50 và 60
W DW 10,20,30,40,50,60
Địa chỉ của biến mảng gọi là địa chỉ cơ sở của mảng ( base address of the array) . Trong mảng W thì địa chỉ cơ sở là 10 .Nếu địa chỉ offset của W là 0200h thì trong bộ nhớ mảng 6 phần tử nói trên sẽ như sau :

Offset address Symbolic address Decimal content
0200h W 10
0202h W+2h 20
0204h W+4h 30
0206h W+6h 40
0208h W+8h 50
020Ah W+Ah 60

Toán tử DUP ( Duplicate)
Có thể định nghĩa một mảng mà các phần tử của nó có cùng một giá trị ban
đầu bằng phép DUP như sau :
Ví dụ :
repeat_count DUP ( value)
lặp lại một số ( VALUE) n lần (n = repeat_count)
GAMMA DW 100 DUP (0) ; tạo một mảng 100 từ mà giá trị ban đâù là 0 .
DELTA DB 212 DUP (?) ; tạo một mảng 212 byte giá trị chưa xác định
DUP có thể lồng nhau , ví dụ : LINE DB 5,4,3 DUP (2, 3 DUP (0) ,1)
tương đương với : LINE DB 5,4,2,0,0,0,1,2,0,0,0,1,2,0,0,0,1

Vị trí các phần tử của một mảng
Địa chỉ của một phần tử của mảng có thể được xác định bằng cách cộng một hằng số với địa chỉ cơ sở . Giả sử A là một mảng và S chỉ ra số byte của một phần tử của mảng ( S=1 đối với mảng byte và S=2 đối với mảng từ ) . Vị trí của các phần tử của mảng A có thể tính như sau :

Position Location
1 A
2 A+1xS
3 A+2xS
. .
. .
. .
N A+ (N-1)xS

Ví dụ: Trao đổi phần tử thứ 10 và thứ 25 của mảng từ W . Phần tử thứ 10 là W[10] có địa chỉ là W+9x2=W+18 Phần tử thứ 25 là W[25] có địa chỉ là W+24x2=W+48 Vì vậy có thể trao đổi chúng như sau :
MOV AX,W+18 ; AX = W[10]
XCHG W+48,AX ; AX= W[25]
MOV W+18, AX ; complete exchange
7.2 Các chế độ địa chỉ ( addressing modes)
Cách thức chỉ ra toán hạng trong lệnh gọi là chế độ địa chỉ . Các chế độ địa chỉ thường dùng là :
Chế độ địa chỉ bằng thanh ghi ( register mode) : toán hạng là thanh ghi
Chế độ địa chỉ tức thời ( immediate mode) : toán hạng là hằng số
Chế độ địa chỉ trực tiếp ( direct mode) : toán hạng là biến
Ví dụ : MOV AX,0 ; AX là register mode còn 0 là immediate mode
ADD ALPHA,AX ; ALPHA là direct mode
Ngoài ra còn có 4 chế độ địa chỉ khác là :
Chế độ địa chỉ gián tiếp bằng thanh ghi ( register indirect mode )
Chế độ địa chỉ cơ sở (based mode)
Chế độ địa chỉ chỉ số ( indexed mode)
Chế độ địa chỉ chỉ số sơ sở ( based indexed mode)
7.2.1 Chế độ địa chỉ gián tiếp bằng thanh ghi
Trong chế độ địa chỉ gián tiếp bằng thanh ghi, địa chỉ offset của toán hạng được chưá trong 1 thanh ghi. Chúng ta nói rằng thanh ghi là con trỏ (pointer) của vị trí nhớ. Dạng toán hạng là [register]. Trong đó register là các thanh ghi BX, SI , DI , BP. Đối với các thanh ghi BX , SI , DI thì thanh ghi đoạn là DS . Còn thanh ghi đoạn của BP là SS .
Ví dụ: giả sử rằng SI = 100h và từ nhớ tại địa chỉ DS:0100h có nội dung là 1234h .
Lệnh MOV AX,[SI] sẽ copy 1234h vào AX .
Giả sử rằng nội dung các thanh ghi và nội dung của bộ nhớ tương ứng là như sau :

Thanh ghi nội dung offset nội dung bộ nhớ
AX 1000h 1000h 1BACh
SI 2000h 2000h 20FFh
DI 3000h 3000h 031Dh

Hãy cho biết lệnh nào sau đây là hợp lý , offset nguồn và kết qủa của các lệnh hợp lý :
Lời giải :

Source offset Result
a. 1000h 1BACh
b. 2000h 20FFh
c. illegal source register ( must be BX,SI,DI)
d. illegal memory-memory add
e. 3000h 031Eh

a.MOV BX,[BX]
b.MOV CX,[SI]
c.MOV BX,[AX]
d.ADD [SI],[DI]
e.INC [DI]

Ví dụ 2 : Viết đoạn mã để cộng vào AX 10 phần tử của một mảng W định nghĩa như sau :
W DW 10,20,30,40,50,60,70,80,90,100
Giải :
XOR AX,AX ; xoá AX
LEA SI,W ; SI trỏ tới địa chỉ cơ sở ( base) của mảmg W .
MOV CX,10 ; CX chưá số phần tử của mảng
ADDITION:
ADD AX,[SI] ; AX=AX + phần tử thứ nhất
ADD SI,2 ; tăng con trỏ lên 2
LOOP ADDITION ; lặp

Ví dụ 3 : Viết thủ tục để đảo ngược một mảng n từ . Điều này có nghĩa là phần tử thứ nhất sẽ đổi thành phần tử thứ n , phần tử thứ hai sẽ thành phần tử thứ n-1 ... Chúng ta sẽ dùng SI như là con trỏ của mảng còn BX chứa số phần tử của mảng (n từ) .
Giải : Số lần trao đổi là N/2 lần . Nhớ rằng phần tử thứ N của mảng có địa chỉ A+2x(N-1)
Đoạn mã như sau :
REVERSE PROC
; input: SI= offset of array
; BX= number of elements
; output : reverse array
PUSH AX ; cất các thanh ghi
PUSH BX
PUSH CX
PUSH SI
PUSH DI
; DI chỉ tới phần tử thứ n
MOV DI,SI ; DI trỏ tới từ thứ nhất
MOV CX,BX ; CX=BX=n : số phần tử
DEC BX ; BX=n-1
SHL BX,1 ;BX=2x(n-1)
ADD DI,BX ;DI = 2x(n-1) + offset của mảng : chỉ tới phần tử thứ n
SHR CX,1 ;CX=n/2 : số lần trao đổi
; trao đổi các phần tử
XCHG_LOOP:
MOV AX,[SI] ; lấy 1 phần tử ở nửa thấp của mảng
XCHG AX,[DI] ; đưa nó lên nửa cao của mảng
MOV [SI],AX ; hoàn thành trao đổi
ADD SI,2 ; SI chỉ tới phần tử tiếp theo của mảng
SUB DI,2 ; DI chỉ tới phần tử thứ n-1
LOOP
XCHG_LOOP
POP DI
POP SI
POP CX
POP BX
POP AX
RET
REVERSE ENDP
7.2.2 Chế độ địa chỉ chỉ số và cơ sở
Trong các chế độ địa chỉ này , địa chỉ offset của toán hạng có được bằng cách cộng một số gọi là displacement với nội dung của một thanh ghi.
Displacement có thể là : địa chỉ offset của một biến , ví dụ A một hằng ( âm hoặc dương ), ví dụ -2 địa chỉ offset của một biến cộng với một hằng số , ví dụ A+4
Cú pháp của một toán hạng có thể là một trong các kiểu tương đương sau :
[register + displacement]
[displacement + register]
[register]+ displacement]
[displacement]+ register
displacement[register]
Các thanh ghi phải là BX , SI , DI (địa chỉ đoạn phải là thanh ghi DS) và BP (thanh ghi
SS chứa địa chỉ đoạn)
Chế độ địa chỉ được gọi là cơ sở (based) nếu thanh ghi BX (base register) hoặc BP (base
pointer) được dùng .
Chế độ địa chỉ được gọi là chỉ số ( indexed) nếu thanh ghi SI( source index) hoặc DI
(destination index) được dùng .
Ví dụ : Giả sử rằng W là mảng từ và BX chưá 4 . Trong lệnh MOV AX,W[BX]
displacement là địa chỉ offset của biến W . Lệnh này sẽ di chuyển phần tử có điạ chỉ W+4
vào thanh ghi AX . Lệnh này cũng có thể viết dưới các dạng tương đương sau :
MOV AX, [W+BX]
MOV AX, [BX+W]
MOV AX, W+[BX]
MOV AX, [BX]+W
Lấy ví dụ khác , giả sử rằng SI chứa địa chỉ của mảng từ W . Trong lệnh MOV AX,[SI+2]
displacement là 2 .Lệnh này sẽ di chuyển nội dung của từ nhớ W+2 tới AX . Lệnh này
cũng có thể viết dưới các dạng khác :
MOV AX,[2+SI]
MOV AX,2+[SI]
MOV AX,[SI]+2
MOV AX,2[SI]
Với chế độ địa chỉ cơ sở có thể viết lại code cho bài toán tính tổng 10 phần tử của mảng
như sau :
XOR AX,AX ; xoá AX
XOR BX,BX ; xoá BX ( thanh ghi cơ sở )
MOV CX,10 ; CX= số phần tử =10
ADDITION:
ADD AX,W[BX] ; sum=sum+element
ADD BX,2 ; trỏ tới phần tử thứ hai
LOOP ADDITION
Ví dụ : Giả sử rằng ALPHA được khai báo như sau :
ALPHA DW 0123h,0456h,0789h,0ADCDH
trong đoạn được địa chỉ bởi DS và giả sử rằng :
BX=2 [0002]= 1084h
SI=4 [0004]= 2BACh
DI=1
Chỉ ra các lệnh nào sau đây là hợp lệ, địa chỉ offset nguồn và số được chuyển .
a. MOV AX,[ALPHA+BX]
b. MOV BX,[BX+2]
c. MOV CX,ALPHA[SI]
d. MOV AX,-2[SI]
e. MOV BX,[ALPHA+3+DI]
f. MOV AX,[BX]2
g.MOV BX,[ALPHA+AX]
Giaûi :

Source offset
Number moved
a. ALPHA+2 0456h
b. 2+2 2BACh
c. ALPHA+4 0789h
d. -2+4=+2 1084h
e. ALPHA+3+1=ALPHA+4 0789h


d. illegal form source operand ...[BX]2
g. illegal ; thanh ghi AX là không được phép
Ví dụ sau đây cho thấy một mảng được xử lý như thế nào bởi chế độ địa chỉ chỉ số và cơ sở .
Ví dụ : Đổi các ký tự viết thường trong chuỗi sau thành ký tự viết hoa .
MSG DB 'co ty lo lo ti ca '
Giải : MOV CX,17 ; số ký tự chứa trong CX=17
XOR SI,SI ; SI chỉ số cho ký tự
CMP MSG[SI], ' ' ; blank?
JE NEXT ; yes , skip
AND MSG[SI],0DFH ; đổi thành chữ hoa
NEXT:
INC SI ; chỉ số ký tự tiếp theo
LOOP TOP ; lặp
7.2.3 Toán tử PTR và toán tử giả LABEL
Trong các chương trước chúng ta đã biết rằng các toán hạng của một lệnh phải cùng loại , tức là cùng là byte hoặc cùng là từ .Nếu một toán hạng là hằng số thì ASM sẽ chuyển chúng thành loại tương ứng với toán hạng kia . Ví dụ , ASM sẽ thực hiện lệnh MOV AX,1 như là lệnh toán hạng từ . Tương tự , ASM sẽ thực hiện lệnh MOV BH,5 như là lệnh byte . Tuy nhiên , lệnh MOV [BX],1 là không hợp lệ vì ASM không biết toán hạng chỉ bởi thanh ghi BX là toán hạng byte hay toán hạng từ .Có thể khắc phục điều này bằng toán tử PTR như sau :
MOV BYTE PTR [BX],1 ; toán hạng đích là toán hạng byte
MOV WORD PTR [BX],1 ; toán hạng đích là toán hạng từ
Ví dụ : Thay ký tự t thành T trong chuỗi được định nghĩa bởi :
MSG DB 'this is a message'
Cách 1: Dùng chế độ địa chỉ gián tiếp thanh ghi :
LEA SI,MSG ; SI trỏ tới MSG
MOV BYTE PTR [SI],'T' ; thay t bằng T
Cách 2 : Dùng chế độ địa chỉ chỉ số :
XOR SI,SI ; xoá SI
MOV MSG[SI],'T ' ; thay t bởi T
Ở đây không cần dùng PTR vì MSG là biến byte .Nói chung toán tử PTR được dùng để khai báo loại ( type) của toán hạng . Cú pháp chung của nó như sau:
Type PTR address_expression
Trong đó Type : byte , word , Dword
Addres_expression : là các biến đã được khai báo bởi DB,DW, DD . Ví dụ chúng ta có 2
khai báo biến như sau :
DOLLARS DB 1AH
CENTS DB 52H
và chúng ta muốn di chuyển DOLLARS vào AL , di chuyển CENTS vào AH chỉ bằng một lệnh MOV duy nhất . Có thể dùng lệnh sau :
MOV AX, WORD PTR DOLLARS ; AL=DOLLARS và AH=CENTS
Toán tử giả LABEL : Có một cách khác để giải quyết vấn đề xung đột về loại toán hạng như trên bằng cách dùng toán tử giả LABEL như sau đây :
MONEY LABEL WORD
DOLLARS DB 1AH
CENTS DB 52H
Các lệnh trên đây khai báo biến MONEY là bi ến từ với 2 thành phần là DOLLARS và CENTS . Trong đó DOLLRAS có cùng địa chỉ với MONEY .
Lệnh MOV AX, MONEY
Tương đương với 2 lệnh :
MOV AL , DOLLARS
MOV AH, CENTS
Ví dụ: Giả sử rằng số liệu được khai báo như sau :
.DATA
A DW 1234h
B LABEL BYTE
DW 5678h
C LABEL WORD
C1 DB 9Ah
C2 DB 0bch
Hãy cho biết các lệnh nào sau đây là hợp lệ và kết qủa của lệnh .
a. MOV AX,B
b. MOV AH,B
c. MOV CX,C
d. MOV BX,WORD PTR B
e. MOV DL,WORD PTR C
f. MOV AX, WORD PTR C1
Giải :
a. không hợp lệ
b. hợp lệ , 78h
c. hợp lệ , 0BC9Ah
d. hợp lệ , 5678h
e. hợp lệ , 9Ah
f. hợp lệ , 0BC9Ah

7.2.4 Chiếm đoạn ( segment override)
Trong chế độ địa chỉ gián tiếp bằng thanh ghi , các thanh ghi con trỏ BX,SI hoặc DI chỉ ra địa chỉ offset còn thanh ghi đoạn là DS . Cũng có thể chỉ ra một thanh ghi đọan khác theo cú pháp sau : segment_register : [ pointer_register] Ví dụ : MOV AX, ES:[SI]
nếu SI=0100h thì địa chỉ của toán hạng nguồn là ES:0100h
Việc chiếm đọan cũng có thể dùng với chế độ địa chỉ chỉ số và chế độ địa chỉ cơ sở .
7.2.5 Truy xuất đoạn stack
Như chúng ta đã nói trên đây khi BP chỉ ra một địa chỉ offset trong chế độ địa chỉ gián tiếp bằng thanh ghi , SS sẽ cung cấp số đoạn . Điều này có nghĩa là có thể dùng dùng BP để truy xuất stack .
Ví dụ : Di chuyển 3 từ tại đỉnh stack vào AX,BX,CX mà không làm thay đổi nội dung của stack .
MOV BP,SP ; BP chỉ tới đỉnh stack
MOV AX,[BP] ; copy đỉnh stack vào AX
MOV BX,[BP+2] ; copy từ thứ hai trên stack vào BX
MOV CX,[BP+4] ; copy từ thứ ba vào CX

7.3 Sắp xếp số liệu trên mảng
Việc tìm kiếm một phần tử trên mảng sẽ dễ dàng nếu như mảng được sắp xếp
(sort). Để sort mảng A gồm N phần tử có thể tiến hành qua N-1 bước như sau :
Bước 1: Tìm số lớn nhất trong số các phần tử A[1]...A[N] . Gán số lớn nhất cho A[N] .
Bước 2 : Tìm số lớn nhất trong các số A[1]...A[N-1]. Gán số lớn nhất cho A[N-1}
.
.
Bước N-1 : Tìm só lớn nhất trong 2 só A[1] và A[2}. Gán só lớn nhất cho A[2]
Ví dụ : giả sử rằng mảng A chứa 5 phần tử là các số nguyên như sau :

Position 1 2 3 4 5
initial 21 5 16 40 7
Bước 1 21 5 16 7 40
Bước 2 7 5 16 21 40
Bước 3 7 5 16 21 40
Bước 4 5 7 16 21 40

Thuật toán
i =N
FOR N-1 times DO
find the position k of the largest element among A[1]..A[i]
Swap A[i] and A[k] ( uses procedure SWAP )
i=i-1
END_FOR
Sau đây là chương trình để sort các phần trong mộ mảng . Chúng ta sẽ dùng thủ tục SELECT để chọn phần tử trên mảng . Thủ tục SELECT sẽ goị thủ tục SWAP để sắp xếp . Chương trình chính sẽ như sau :
TITLE PGM7_3: TEST SELECT
.MODEL SMALL
.STACK 100H
.DATA
A DB 5,2,,1,3,4
.CODE
MAIN PROC
MOV AX,@DATA
MOV DS,AX
LEA SI,A
MOV BX,5 ; số phần tử của mảng chứa trong BX
CALL SELECT
MOV AH,4CH
INT 21H
MAIN ENDP
INCLUDE C:\ASM\SELECT.ASM
END MAIN

Tập tin SELECT.ASM chứa thủ tục SELECT vàthủ tục SWAP được viết như sau tại C:\ASM .
SELECT PROC
; sắp xếp mảng byte
; input: SI = địa chỉ offset của mảng
BX= số phần tử ( n) của mảng
; output: SI = điạ chỉ offset của mảng đã sắp xếp .
; uses : SWAP
PUSH BX
PUSH CX
PUSH DX
PUSH SI
DEC BX ; N = N-1
JE END_SORT ; Nếu N=1 thì thoát
MOV DX,SI ; cất địa chỉ offfset của mảng vào DX
; lặp N-1 lần
SORT_LOOP:
MOV SI,DX ; SI trỏ tới mảng A
MOV CX,BX ; CX = N -1 số lần lặp
MOV DI,SI ; DI chỉ tới phần tử thứ nhất
MOV AL,[DI] ; AL chứa phần tử thứ nhất
; tìm phần tử lớn nhất
FIND_BIG:
INC SI ; SI trỏ tới phần tử tiếp theo
CMP [SI],AL ; phần tử tiếp theo > phần tử thứ nhất
ING NEXT ; không , tiếp tục
MOV DI,SI ; DI chứa địa chỉ của phần tử lớn nhất
MOV AL,[DI] ; AL chứa phần tử lớn nhất
NEXT:
LOOP FIND_BIG
; swap phần tử lớn nhất với phần tử cuối cùng
CALL SWAP
DEC BX ; N= N-1
JNE SORT_LOOP ; lặp nếu N<>0
END_SORT:
POP SI
POP DX
POP CX
POP BX
RET
SELECT ENDP
SWAP PROC
; đổi chỗ 2 phần tử của mảng
; input : SI= phần tử thứ nhất
; DI = phần tử thứ hai
; output : các phần tử đã trao đổi
PUSH AX ; cất AX
MOV AL,[SI] ; lấy phần tử A[i]
XCHG AL,[DI] ; đặt nó trên A[k]
MOV [SI],AL ; đặt A[k] trên A[i]
POP AX ; lấy lại AX RET
SWAP ENDP
Sau khi dịch chương trình , có thể dùng DEBUG để chạy thử và test kết qủa .
7.4 Mảng 2 chiều
Mảng 2 chiều là một mảng của một mảng , nghĩa là một mảng 1 chiều mà các phần
tử của nó là một mảng 1 chiều khác . Có thể hình dung mảng 2 chiều như một ma trận
chữ nhật . Ví dụ mảng B gồm có 3 hàng và 4 cột ( mảng 3x4) như sau :

ROW \ COLUMN 1 2 3 4
1 B[1,1] B[1,2] B[1,3] B[1,4]
2 B[2,1] B[2,2] B[2,3] B[2,4]
3 B[3,1] B[3,2] B[3,3] B[3,4]

Bởi vì bộ nhớ là 1 chiều vì vậy các phần tử của mảng 2 chiều phải được lưu trữ trên
bộ nhớ theo kiểu lần lượt . Có 2 cách được dùng :
Cách 1 là lưu trữ theo thứ tự dòng : trên mảng lưu trữ các phần tử của dòng 1 rồi đến
các phần tử của dòng 2 ...
Cách 2 là lưu trữ theo thứ tự cột : trên mảng lưu trữ các phần tử của cột 1 rồi đến các
phần tử của cột 2...
Giả sử mảng B chứa 10,20,30,40 trên dòng 1 chứa 50,60,70,80 trên dòng 2 chưá
90,100,110,120 trên dòng 3
Theo trật tự hàng chúng được lưu trữ như sau :

B DW 10,20,30,40
DW 50,60,70,80
DW 90,100,110,120

Theo trật tự cột chúng được lưu trữ như sau :

B DW 10,50,90
DW 20,60,100
DW 30,70,110
DW 40,80,120

Hầu hết các ngôn ngữ cấp cao biên dịch mảng 2chiều theo trật tự dòng . Trong ASM ,
chúng ta có thể dùng một trong 2 cách :
Nếu các thành phần của một hàng được xử lý lần lượt thì cách lưu trữ theo trật tự hàng
được dùng . Ngược lại thì dùng cách lưu trữ theo trật tự cột .
Xác định một phần tử trên mảng 2 chiều :
Giả sử rằng mảng A gồm MxN phần tử lưu trữ theo trật tự dòng . Goị S là độ lớn của
một phần tử : S=1 nếu phần tử là byte , S=2 nếu phần tử là từ . Để tìm phần tử thứ
A[i,j] thì cần tìm : hàng i và tìm phần tử thứ j trên hàng này . Như vậy phải tiến hành
qua 2 bước :
Bước 1: Hàng 1 bắt đầu tại vị trí A . Vì mỗi hàng có N phần tử , do đó
Hàng 2 bắt đầu tại A+ NxS .
Hàng 3 bắt đầu tại A+2xNxS .
Hàng thứ i bắt đầu tại A+(i-1)xSxN .
Bước 2: Phần tử thứ j trên một hàng cách vị trí đầu hàng (j-1)xS byte Từ 2 bước trên suy
ra rằng trong mảng 2 chiều NxM phần tử mà chúng được lưu trữ theo trật tự hàng thì
phần tử A[i,j] có địa chỉ được xác định như sau : A+((i-1)xN + (j-1))x S (1)
Tương tự nếu lưu trữ theo trật tự cột thì phần tử A[i,j] có địa chỉ như sau :
A+(i-1)+(j--)xM)xS (2)
Ví dụ : Giả sử A là mảng MxN phần tử kiểu từ ( S=2) được lưu trữ theo kiểu trật tự
hàng . Hỏi :
Hàng i bắt đầu tại địa chỉ nào ? Cột j bắt đầu tại điạ chỉ nào ?
Hai phần tử trên một cốt cách nhau bao nhiêu bytes
Giải :
Hàng i bắt đầu tại A[i,1] theo công thức (1) thì nó có địa chỉ là : A+(i-1)xNx2
Cột j bắt đầu tại A[1,j ] theo công thức (1) thì nó có địa chỉ : A+(j-1)x2
Vì có N cột nên 2 phần tử trên cùng một cột cách nhau 2xN byte .
7.5 Chế độ địa chỉ chỉ số cơ sở Trong chế độ này , địa chỉ offset của toán hạng là tổng
của :
1. nội dung của thanh ghi cơ sở ( BX or BP)
2. nội dung của thanh ghi chỉ số ( SI or DI)
3. địa chỉ offset của 1 biến ( tuỳ chọn)
4. một hằng âm hoặc dương ( tuỳ chọn)
Nếu thanh ghi BX được dùng thì DS chứa số đoạn của địa chỉ toán hạng .Nếu
BP được dùng thì SS chưá số đoạn . Toán hạng được viết theo 4 cách dưới đây:
1. variable[base_register][index_register]
2. [base_register + index_register + variable + constant ]
3. variable [ base_register + index_register + constant]
4. constant [ base _ register + index_register + variable]
Trật tự của các thành phần trong dấu ngoặc là tuỳ ý .
Ví dụ , giả sử W là biến từ , BX=2 và SI =4 . Lệnh MOV AX, W[BX][SI]
sẽ di chuyển nội dung của mảng tại địa chỉ W+2+4 = W+6 vào thanh ghi AX Lệnh này
cũng có thể viết theo 2 cách sau :
MOV AX,[W+BX+SI]
MOV AX,W[BX+SI]
Chế độ địa chỉ chỉ số cơ sở thường được dùng để xử lý mảng 2 chiều như ví dụ sau : Giả sử rằng A là mảng 5x7 từ được lưu trữ theo trật tự dòng .
Viết đoạn mã dùng chế độ địa chỉ chỉ số để :
1) xóa dòng 3
2) xoá cột 4
Giải :
1) Dòng i bắt đầu tại A+(i-1)xNx2 . Như vậy dòng 3 bắt đầu tại A+(2-1)x7x2= A + 28 . Có thể xóa dòng 3 như sau :
MOV BX,28 ; BX chỉ đến đầu dòng 3
XOR SI,SI ; SI sẽ chỉ mục cột
MOV CX,7 ; CX= số phần tử của một hàng
CLEAR:
MOV A[BX][SI],0 ; xoá A[3,1]
ADD SI,2 ; đến cột tiếp theo
LOOP CLEAR
2) Cột j bắt đầu tại điạ chỉ A + (j-1)x2 . Vậy cột 4 bắt đầu tại điạ chỉ A+(4-1)x2 = A+ 6 . Hai phần tử trên một cột cách nhau Nx2 byte , ở đây N=7 , vậy 2 phần tử cách nhau 14 byte . Có thể xóa cột 4 như sau :
MOV SI,6 ; SI chỉ đến cột 4
XOR BX,BX ; BX chỉ đến hàng
MOV CX,5 ; CX= 5 : số phần tử trên một cột
CLEAR:
MOV A[BX][SI],0 ; Xoá A[i,4]
ADD BX,1 ; đến dòng tiếp theo
LOOP CLEAR
7.6 Ưng dụng để tính trung bình
Giả sử một lớp gồm 5 sinh viên và có 4 môn thi . Kết qủa cho bởi mảng 2 chiều như sau :

Tên Sinh viên TEST1 TEST2 TEST3 TEST4
MARY 67 45 98 33
SCOTT 70 56 87 44
GEORGE 82 72 89 40
BETH 80 67 95 50
SAM 78 76 92 60

Chúng ta sẽ viết1 chương trình tính điểm trung bình cho mỗi bài thi . Để làm điều này có thể tổng theo cột rồi chia cho 5 .
Thuật toán :
1. j = 4
2. repeat
3. Sum the scores in column j
4. divide sum by 5 to get average in column j
5. j = j - 1
5. Until j = 0

Trong đó bước 3 có thể làm như sau :
Sum[j]= 0
i = 1
FOR 5 times DO
Sum[j]= Sum[j]+ Score[i, j]
i = i + 1
END_FOR

Chương trình có thể viết như sau :
TITLE PGM7_4 : CLASS AVERAGE
.MODEL SMALL
.STACK 100H
.DATA
FIVE DB 5
SCORES DW 67,45,98,33 ; MARY
DW 70,56,87,44 ;SCOTT
DW 82,72,89,40 ;GEORGE
DW 80,67,,95,50 ; BETH
DW 78,76,92,60 ;SAM
AVG DW 5 DUP (0)
.CODE
MAIN PROC
MOV AX,@DATA
MOV DS,AX
;J=4
REPEAT:
MOV SI,6 ; SI chỉ đến cột thứ 4
XOR BX,BX ; BX chỉ hàng thứ nhất
XOR AX,AX ; AX chứa tổng theo cột
; Tổng điểm trên cột j
FOR:
ADD AX , SCORES[BX+SI]
ADD BX,8 ; BX chỉ đến hàng thứ 2
LOOP FOR
; end_for
; tính trung bình cột j
XOR DX,DX ; xoá phần cao của số bị chia (DX:AX)
DIV FIVE ; AX = AX/5
MOV AVG[SI],AX ; cất kết qủa trên mảng AVG
SUB SI,2 ; đến cột tiếp
; until j=0
JNL REPEAT
;DOS EXIT
MOV AH,4CH
INT 21H
MAIN ENDP
END MAIN

Sau khi biên dịch chương teình có thể dùng DEBUG để chạy và xem kết qủa bằng lệnh DUMP.
7.7 Lệnh XLAT Trong một số ứng dụng cần phải chuyển số liệu từ dạng này sang dạng khác . Ví dụ IBM PC dùng ASCII code cho các ký tự nhưng IBM Mainframes dùng EBCDIC ( Extended Binary Coded Decimal Interchange Code) . Để chuyển một chuỗi ký tự đã được mã hoá bằng ASCII thành EBCDIC , một chương trình phải thay mã ASCII của từng ký tự trong chuỗi thành mã EBCDIC tương ứng .
Lệnh XLAT ( không có toán hạng ) được dùng để đổi một giá trị byte thành một giá trị khác chứa trong một bảng . AL phải chứa byte cần biến đổi
DX chứa điạ chỉ offset của bảng cần biến đổi
Lệnh XLAT sẽ :
1) cộng nội dung của AL với địa chỉ trên BX để tạo ra điạ chỉ trong bảng
2) thay thế giá trị của AL với giá trị tìm thấy trong bảng
Ví dụ , giả sử rằng nội dung của AL là trong vùng 0 đến Fh và chúng ta muốn thay nó bằng mã ASCII của số hex tương đương nó , tức là thay 6h bằng 036h='6' , thay Bh bằng 042h="B" . Bảng biến đổi là :

TABLE DB 030h ,031h , 032h ,033h ,034h , 035h , 036h, 037h,038h,039h
DB 041h , 042h ,043h , 044h, 045h , 046h

Ví dụ, để đổi 0Ch thành "C", chúng ta thực hiện các lệnh sau : MOV AL,0Ch ; số cần biến đổi
LEA BX,TABLE ; BX chưá điạ chỉ offset của bảng
XLAT ; AL chứa "C"
Ở đây XLAT tính TABLE + Ch = TABLE +12 và thay thế AL bởi 043h . Nếu AL chứa một số không ở trong khỏang 0 đến 15 thì XLAT sẽ cho một giá trị sai .
Ví dụ: Mã hoá và giải mã một thông điệp mật
Chương trình này sẽ :
Nhắc nhở người dùng nhập vào một thông điệp
Mã hoá nó dưới dạng không nhận biết được , In chúng ra ở dòng tiếp theo
Dịch chúng trở lại dạng ban đầu rồi in chúng ở dòng tiếp theo
Khi chạy ct màn hình sẽ có dạng sau :
ENTER A MESSAGE :
DAI HOC ; input
OXC BUC OX EXK ; encode
DAI HOC ; translated
Thuật toán như sau : Print prompt
Read and encode message
Go to anew line
Print encoded message go to a new line
translate and print message

TITLE PGM7_5 : SECRET MESSAGE
.MODEL SMALL
.STACK 100H
.DATA
;ALPHABET ABCDEFGHIJKLMNOPQRSTUVWXYZ
CODE_KEY DB 65 DUP ( ' '), ' XQPOGHZBCADEIJUVFMNKLRSTWY'
DB 37 DUP (' ') ; 128 ký tự của bảng mã ASCII CODED
DB 80 dup ('$') ; 80 ký tự được gõ vào
DECODE_KEY DB 65 DUP (' '),'JHIKLQEFMNTURSDCBVWXOPYAZG'
DB 37 DUP (' ')
PROMPT DB 'ENTER A MESSAGE :',0DH,0AH,'$' CRLF
DB 0DH,0AH,'$'
.CODE
MAIN PROC
MOV AX,@DATA
MOV DS, AX
; in dấu nhắc
MOV AH,9
LEA DX,PROMPT
INT 21H
; đọc và mã hoá ký tự
MOV AH,1
LEA BX,CODE_KEY
; BX chỉ tới CODE_KEY
LEA DI, CODED ; DI chỉ tới thông điệp đã mã hoá
WHILE_:
INT 21h ; đọc ký tự vào AL
CMP AL ,0DH ; có phải là ký tự CR
JE ENDWHILE ; đúng , đến phần in thông điệp đã mã hoá
XLAT ; mã hoá ký tự
MOV [DI], AL ; cất ký tự trong CODE
JMP WHILE_ ; xử lý ký tự tiếp theo
; xuống hàng
MOV AH,9
LEA DX,CRLF
INT 21H
; in thông điệp đã mã hoá
LEA DX,CODED
INT 21H
; xuống hàng
LEA DX,CRLF
INT 21H
; giải mã thông điệp và in nó
MOV AH,2
LEA BX,DECODE_KEY ; BX chứa điạ chỉ bảng giải mã
LEA SI,CODED ; SI chỉ tới thông điệp đã mã hoá
WHILE1:
MOV AL,[SI] ; lấy ký tự từ thông điệp đã mã hoá
CMP AL.'$' ; có phải cuối thông điệp
JE ENDWHILE1 ; kết thúc
XLAT ; giải mã
MOV DL,AL ;đặt ký tự vào DL
INT 21H ; in ký tự
INC SI ; SI=SI+1
JMP WHILE1 ; tiếp tục
ENDWHILE1:
MOV AH,4CH
INT 21H
MAIN ENDP
END MAIN
Trong chương trình có đọan số liệu với các khai báo sau :
; ALPHABET ABCDEFGHIJKLMNOPQRSTUVWXYZ
Cho biết bảng chữa cái tiếng Anh
CODE_KEY DB 65 DUP ( ' '), ' XQPOGHZBCADEIJUVFMNKLRSTWY'
DB 37 DUP (' ')
Khai báo 128 ký tự của bảng mã ASCII , trong đó thứ tự các ký tự hoa là tuỳ ý .
CODED DB 80 dup ('$')
80 ký tự được gõ vào , giá trị ban đầu là $ để có thể in bằng hàm 9 ngắt 21h
DECODE_KEY DB 65 DUP (' '), 'JHIKLQEFMNTURSDCBVWXOPYAZG'
DB 37 DUP (' ')
Bảng giải mã được thiết lập theo cách mã hoá , nghĩa là trong phần mã hoá chúng ta đã mã hoá 'A' thành 'X' vì vậy khi giải mã 'X' phải giải mã thành 'A' ...
Các ký tự gõ vào không phải là ký tự hoa đếu được chuyển thành ký tự trống.

10default Re: Co it dap an cau hoi VXL-VDK on 13/10/2011, 12:50 pm

THPTDH


Moderator
Moderator
Loading
very good.thanks

Sponsored content


Loading

Xem chủ đề cũ hơn Xem chủ đề mới hơn Về Đầu Trang  Thông điệp [Trang 1 trong tổng số 1 trang]

Permissions in this forum:
Bạn không có quyền trả lời bài viết