2011-01-31 20 views
5

Tôi vừa mới bắt đầu học ngôn ngữ Assembly. Trong java, nếu chúng ta có một mảng, chúng ta luôn có thể sử dụng array.length để lấy chiều dài của nó. Có một thứ như vậy trong hội đồng? Nếu có, ai đó có thể hướng dẫn tôi ở đây không?Cách kiểm tra "độ dài của mảng" trong Ngôn ngữ assembly (ASM),

Edit:

lời xin lỗi của tôi, tôi biết lắp ráp không có mảng, tôi đã cố gắng để đơn giản hóa mọi thứ.

Những gì tôi có nghĩa là, nếu ví dụ tôi có một biến

data DB 1,2,3,5,7,8,9,10 

Cho rằng DB có thể chứa bất kỳ số lượng các yếu tố, làm thế nào tôi có thể kiểm tra tổng biến nó chứa?

Something như java, nơi sử dụng int mảng để lưu trữ này

int data = {1,2,3,4,57,8,9,10}; 

Chúng ta có thể chỉ data.length để tìm tổng amountt của các yếu tố.

+0

Có rất nhiều ngôn ngữ lắp ráp, mà một trong những bạn đang chỉ ra? –

+3

Không có thứ gì như độ dài cố định của mảng. Mảng chỉ là một đoạn bộ nhớ mà bạn đặt mọi thứ vào. Bạn không có bất kỳ cách nào để biết kích thước của nó là gì; bạn sẽ cần tự mình theo dõi điều này. –

+0

Không ai từng chỉ ra kiến ​​trúc mà OP đang hỏi. –

Trả lời

2

Không có thứ gì như một mảng trong hội đồng (theo như tôi biết). Bạn được tự do phát minh ra một mảng hoạt động như thế nào nếu bạn muốn.

Nếu bạn đang đọc lắp ráp được tạo bởi trình biên dịch thì bạn sẽ phải hỏi cụ thể về trình biên dịch đó.

Một cách để làm điều này là cho phép byte đầu tiên của mảng lưu trữ độ dài của mỗi phần tử. Một cách khác sẽ là vô hiệu hóa mảng (thường là cách chuỗi được duy trì).

6

Hội nghị có nhiều điểm yếu hơn Java. Điều này, trong số những thứ khác, có nghĩa là không có những thứ như một "mảng". Ít nhất là ở dạng Java an toàn mà bạn biết.

Điều gì sẽ tương đương với một mảng đang phân bổ một đoạn bộ nhớ và coi nó là một mảng. Độ dài và như vậy bạn sẽ phải tự quản lý, vì tất cả những gì bạn có là một đoạn bộ nhớ chứa dữ liệu của bạn. Nếu bạn muốn lưu trữ bất kỳ siêu dữ liệu nào, chẳng hạn như độ dài, bạn sẽ phải tự làm điều đó.

Mảng như bạn biết trong Java chứa siêu dữ liệu chẳng hạn như độ dài và kiểm tra giới hạn. Những điều tương tự bạn sẽ phải làm, chỉ có chúng ẩn nó để bạn sẽ không phải lo lắng về những điều đó.

tôi đề nghị bạn hãy nhìn vào những điều sau đây để xem hướng dẫn về cách người ta thường sẽ tạo ra và sử dụng những gì là tương đương với một mảng trong lắp ráp:

+0

mmm Sebastian, bởi vì tôi đang mong đợi một số lượng ngẫu nhiên của số nguyên được cho bởi một người dùng, do đó tôi đang cố gắng mã mã của tôi một cách năng động hơn. tôi đã thử – Mike

+0

Nếu bạn cần một số yếu tố, bạn có thể làm một vài điều. Bạn có thể sử dụng một [danh sách liên kết] (http://en.wikipedia.org/wiki/Linked_list), hoặc bạn có thể làm một mảng theo khối, mỗi phần có kích thước như phần tử đầu tiên của chúng và một con trỏ tới đoạn tiếp theo thứ hai của họ. (Hỗn hợp danh sách liên kết và mảng) –

+0

+1 sách đó là cuốn sách hay nhất – BlackBear

10

Cách tốt nhất để trả lời câu hỏi này là sử dụng các ví dụ C. Trong C, có hai cách theo dõi độ dài của một mảng:

  1. Bạn lưu trữ biến cho biết bạn đã tạo mảng bao lâu.
  2. Bạn thực hiện những chuỗi nào và có phần tử cuối cùng là 0.Sau đó, bạn có thể thực hiện một hàm chuỗi "chuỗi" lặp lại trên mảng cho đến khi nó tìm thấy số không.

Ví dụ đầu tiên, tùy thuộc vào bộ lắp ráp bạn đang sử dụng, bạn có thể sử dụng một số thủ thuật. Ví dụ, trong NASM bạn có thể làm điều này:

SECTION .data  

msg: db "Hello World",10,0 ; the 0-terminated string. 
len: equ $-msg    ; "$" means current address. 

Như bạn có thể thấy, chúng ta sử dụng toán tử equ để có được NASM để tính toán sự khác biệt giữa địa chỉ hiện tại và bắt đầu msg mà phải bằng chiều dài của nó. Ngoài ra, bạn chỉ có thể viết chiều dài trong đó dưới dạng chữ số.

Đối với trường hợp thứ hai, bạn có thể dễ dàng viết một hàm nhỏ để thực hiện. Nói thật, nếu bạn:

SECTION .text 

global _mystrlen 

_mystrlen: 

    push ebp  ; conform to C calling conventions. 
    mov  ebp, esp 

    xor  eax, eax 
    lea  ecx, [esp+8] ; load the start of the array into ecx 
    jecxz end   ; jump if [ecx] is zero. 

loop: 
    add  eax, 1  ; could use inc eax as well. 
    add  ecx, 4  ; always increment by (sizeof(int)). Change as appropriate 
    mov  edx, [ecx] ; load ecx 
    cmp  edx, 0  ; compare with zerp 
    je  end  ; if ecx is zero, we're done. 
    jmp  loop  ; if ecx isn't zero, loop until it is. 

end: 
    leave    ; restore stack frame 
    ret    ; return. eax is retval 

Lưu ý rằng tôi chưa thử nghiệm điều đó. Nó chỉ là để cho bạn một ý tưởng.

Sửa Tôi đã thử nghiệm phiên bản x86_64 trên Linux, sử dụng rdi như param1, đi qua trong int arr[10] = {1,2,3,4,5,6,7,8,9,0};. Trả về 9 như mong đợi. Lưu ý rằng trên Linux, dấu gạch dưới trước mystrlen là không cần thiết.

+3

+1 khái niệm 'equ $ -msg' rất hữu ích –

+0

Cảm ơn rất nhiều vì đã viết $ -msg! – Conex

+0

Mặc dù tính năng '$' được áp dụng thực sự, cần lưu ý rằng độ dài chuỗi không bị chấm dứt (trái ngược với chuỗi Pascal) không được tính theo cách đó. Các chuỗi chính nó là thay vì lặp đi lặp lại tìm kiếm một số không byte và số chu kỳ được trả về. Tuy nhiên, phương thức này không thể được sử dụng với các mảng vì chúng cũng cho phép các giá trị bằng 0. Đối với họ thực sự không có cách nào khác hơn là theo dõi độ dài của họ trong một biến. – Powerslave

0

MOV EAX, dữ liệu LENGTHOF

Trả về số mục trong biến mảng.

+0

Trình biên dịch EMU8086 dường như không nhận ra từ khóa 'lengthof'. Trình biên dịch nào bạn sử dụng? –

+0

MASM - https://msdn.microsoft.com/en-us/library/2kz8tk66.aspx – vengy

0

Tôi nghĩ rằng điều này sẽ giúp bạn ....

.data

num db 2,4,6,8,10 

.code

main proc 
mov eax,0 ; initialize with zero 
mov ax,lengthof num 

output = 5

+0

Trình biên dịch EMU8086 dường như không nhận ra từ khóa 'lengthof'. Trình biên dịch nào bạn sử dụng? –

Các vấn đề liên quan