2011-01-31 2 views
5

방금 ​​어셈블리 언어를 배우기 시작했습니다. 자바에서는 Array가 있다면 array.length를 사용하여 길이를 얻을 수 있습니다. 조립에 그런 것이 있습니까? 그렇다면 누군가 나를 안내 해줄 수 있습니까?어셈블리 언어 (ASM)에서 "배열의 길이"를 확인하는 방법

편집 :

내 사과, 내가 조립 배열이없는 알고, 내가 일을 단순화하기 위해 노력했다. 예를 들어 내가이 들어있는 변수 i가 확인할 수있는 방법을 DB 요소의 양을 포함 할 수 있음을 감안할 때

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

, 총 변수가 있다면 무슨 의미가

이었다? 사용 int 배열이

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

우리는 단지 data.length입니다 요소의 총 amountt을 찾을 수 저장할 수있는 자바와 같은

뭔가.

+0

있습니다 많은 어셈블리 언어를하는 당신이 지적한 것이 있습니까? –

+3

배열의 고유 한 길이 같은 것은 없습니다. 배열은 당신이 물건을 넣는 기억의 덩어리 일뿐입니다. 당신은 어떤 크기인지 알 길이 없습니다. 당신은 자신을 추적해야합니다. –

+0

OP가 요구하는 아키텍처에 대해 아무도 언급하지 않았습니다. –

답변

2

조립품에는 배열과 같은 것이 없습니다 (아는 한). 원하는 경우 어레이가 어떻게 작동하는지 자유롭게 발명 할 수 있습니다.

컴파일러에서 생성 한 어셈블리를 읽는 경우 해당 컴파일러에 대해 구체적으로 질문해야합니다.

이렇게하는 한 가지 방법은 배열의 첫 번째 바이트가 각 요소의 길이를 저장할 수 있도록하는 것입니다. 또 다른 방법은 배열을 null로 종료하는 것입니다 (일반적으로 문자열이 유지되는 방법입니다).

6

어셈블리는 Java보다 훨씬 더 수준이 낮습니다. 이것은 무엇보다도 "배열"과 같은 것이 없다는 것을 의미합니다. 적어도 당신이 알고있는 안전한 자바 형식.

배열에 해당하는 것은 메모리 덩어리를 할당하고 배열로 취급하는 것입니다. 길이는 당신이 가지고있는 모든 것이 당신의 데이터를 담고있는 기억의 덩어리이기 때문에 당신 자신을 관리해야 할 것입니다. 길이와 같은 메타 데이터를 저장하려면 직접해야합니다.

Java에서 알고있는 배열에는 길이와 같은 메타 데이터가 포함되어 있으며 경계 검사는 수행하지 않습니다. 이것들은 당신이해야 할 것과 똑같은 일을합니다. 당신이 그 일들에 대해 걱정할 필요가 없도록 숨길뿐입니다.

+0

mmm Sebastian, 나는 사용자에 의해 주어진 정수의 무작위 금액을 기대하고 있기 때문에, 따라서 더 동적 인 방식으로 코드를 코딩하려고합니다. 나는 시도했다 – Mike

+0

가변 수의 요소가 필요한 경우 몇 가지 작업을 수행 할 수 있습니다. [연결된 목록] (http://en.wikipedia.org/wiki/Linked_list)을 사용할 수도 있고, 크기가 첫 번째 요소 인 청크 배열과 다음 청크를 가리키는 포인터를 다음과 같이 지정할 수 있습니다. 그들의 두 번째. (연결된 목록과 배열의 혼합) –

+0

+1 그 책이 가장 좋습니다. – BlackBear

10

이것을 응답하는 제일 방법은 C보기를 사용하기위한 것이다. C에서는 배열의 길이를 추적하는 두 가지 방법이 있습니다.

  1. 배열을 저장 한 기간을 나타내는 변수를 저장합니다.
  2. 문자열이 수행하는 작업을 수행하고 마지막 요소를 0으로 설정합니다.그런 다음 0을 찾을 때까지 배열을 반복하는 "문자열"길이 함수를 구현할 수 있습니다.

첫 번째 예제에서는 사용중인 어셈블러에 따라 몇 가지 트릭을 사용할 수 있습니다. 예를 들어, NASM에서이 작업을 수행 할 수 있습니다 : 당신이 볼 수 있듯이

SECTION .data  

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

, 우리는 현재의 주소와 길이를 동일해야 msg의 시작 사이의 차이를 계산하기 위해 NASM을 얻기 위해 equ 연산자를 사용합니다. 또는 길이를 숫자로 쓸 수 있습니다.

두 번째 경우에는 작은 함수를 쉽게 작성할 수 있습니다. 대충 말하면, 당신이 :

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 

나는 그것을 테스트하지 않았다. 단지 당신에게 아이디어를주는 것입니다.

편집 나는 int arr[10] = {1,2,3,4,5,6,7,8,9,0};를 전달 PARAM1으로 rdi를 사용하여, 리눅스에 x86_64 버전을 테스트했습니다. 예상대로 9을 반환합니다. Linux에서 mystrlen 앞에 오는 밑줄은 필요하지 않습니다.

+3

+1 'equ $ -msg'개념이 매우 유용합니다. –

+0

감사합니다. equ $ -msg! – Conex

+0

'$'기능이 실제로 적용되지만 길이가 0 인 종료 문자열 (파스칼 문자열과 달리)은 그렇게 계산되지 않습니다. 대신 문자열 자체가 반복되어 0 바이트를 찾고 사이클 수가 반환됩니다. 그러나이 메서드는 0 값도 허용해야하므로 배열과 함께 사용할 수 없습니다. 그들에게는 변수의 길이를 추적하는 것 외에는 다른 방법이 없습니다. – Powerslave

0

의 MOV EAX, LENGTHOF 데이터

배열 변수의 항목 수를 반환. 나는이 당신을 도울 것입니다 생각

+0

컴파일러 EMU8086이 'lengthof' 키워드를 인식하지 못하는 것 같습니다. 어떤 컴파일러를 사용합니까? –

+0

MASM - https://msdn.microsoft.com/ko-kr/library/2kz8tk66.aspx – vengy

0

....

.DATA

num db 2,4,6,8,10 

.CODE

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

출력 = 5

+0

컴파일러 EMU8086이 'lengthof' 키워드를 인식하지 못하는 것 같습니다. 어떤 컴파일러를 사용합니까? –