2014-07-05 2 views
0

어셈블리에서 어떻게하면 좋을까요? 편집 :어셈블리 픽셀의 2 차원 배열

그래서 내 루프 꽤 작업 DOS 그래픽 모드를

int start_x=1, start_y=1; 
for(int i=0; i<8; i++){ 
    for(int j=0; j<8; j++){ 
     if(T34[i][j]==1) put_colour_pixel(start_x+i, start_y+j); 
     else put_black_pixel(start_x+i, start_y+j); 
    } 
} 

을 16 비트. 0 테이블에 연결과 1

mov ax, 10 ; Y start line 
    mov bx, 20 ; X start line 
    mov dl, 4 ; colour (red) 
    mov cx, 5 ; loop top counter 
    top: 
     add ax, 1 
     push cx ;loop top counter 
     mov cx, 10 
     inside: 
     add bx, 1 

     push ax 
     push bx 
     push cx 

     call putpixel 

     pop cx 
     pop bx 
     pop ax 
     loop inside 
     mov bx, 20 ;next line X go to start X 

     pop cx ;loop top counter 

    loop top 

하는 방법 //////////////////////////////// /////////////////////////////////////////////////////////////////// /////// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////// // /////////////////////////////////////////////////////////////////// ///////////////////////////////////// 내 새로운 코드 :

segment .data 

    segment .code 
..start: 
    mov ax, 13h 
    int 10h    ; switch to 320x200 mode 

    mov ax, 0a000h  ; The offset to video memory 
    mov es, ax   ; We load it to ES through AX, 
          ; because immediate operation 
          ; is not allowed on ES 

;;;;;;;;;;;;;;;;;;;;;; 

     mov di, T34 
     mov si, 8 
;------------------------------------ 
P1: mov bp, 8 

;---------------- 
P2: cmp BYTE[di], 1 
     jnz short NOHIT 

NOHIT: ; increase the x position 

     push ax 
     push bx 
     push cx 
     mov ax,si ;Y 
     mov bx,bp ;X 
     mov dl, 1 ; here I should take '0' or '1' from table 
     call putpixel 
     pop cx 
     pop bx 
     pop ax 

     inc di ; increase offset address of array 
     dec bp 
     jnz P2 
;------------- 
     ; increase the y position + substract 8 from x position 
     dec si 
     jnz P1 
;------------------------------------ 


;;;;;;;;;;;;;;;;;;;;;;;;; 

    xor ah, ah 
    int 16h    ; keyboard (wait for key) 

    mov ax, 3 
    int 10h    ; go to text mode 

    mov ax, 4c00h 
    int 21h    ; return to DOS, exit code 0 

;;;;;;;;;;;;;;;;;;;;; 

putpixel: 
    push dx    ; mul changes dx too 
    mov cx, 320 
    mul cx    ; multiply Y (ax) by 320 (one row) 
    add ax, bx   ; and add X (bx) (result= dx:ax) 
    mov di, ax 
    pop dx 
    mov [es:di], dl  ; store color/pixel 
    ret 

;;;;;;;;;;;;;;;;;;;;;; 

T34 DB 1,1,1,1,1,1,1,1 
    DB 1,0,0,0,0,0,0,0 
    DB 1,0,0,0,0,0,0,0 
    DB 1,0,0,0,0,0,0,0 
    DB 1,1,1,1,1,1,1,1 
    DB 1,0,0,0,0,0,0,0 
    DB 1,0,0,0,0,0,0,0 
    DB 1,1,1,1,1,1,1,1 

I 순서가 바뀌었고 지금은 왼쪽 구석에 정사각형을 그리고 있습니다 (예상대로). 주문을 변경 했습니까? 나는 그 편지가 회전 될 것이라고 생각하지만 그것은 나에게는 문제가되지 않는다. 나는 나중에 고칠 수있다.

이제 테이블과 색상에서 '0'또는 '1'로 이동해야합니다. 어떤 레지스터가 "0"또는 "1"입니까?

그래서 대부분 색에 문제가 있습니다. 이 방법을 사용해 보았지만 오류가 있습니다. I (0) 또는 파란색 (1)

그래서
push dx 
    mov ax, bp ; X*8 
    mov cx,8 
    mul cx 
    add ax, si ; X*8 +Y 

    add ax, di ; tab0 + X*8+Y 

    mov dl, ax; here is error, here I set the colour 
    pop dx 

나는 그것을 해결하는 방법 :(나는 다른 가능성과 북향 작업을 시도하도록 모르는 세트 색상 블랙을 시도합니다.

+0

"나는 저장해야 ... 변수 ...."사용 레지스터. 작업 속도가 빠르고 주소 지정이 쉽습니다. –

+0

나는 시도 할 것이지만, 처음 시작 x, 시작 y, 루프 카운트를 저장하기에 충분한 등록자인지는 확실하지 않다. (좋은 방법인가 또 다른 것인가?), 픽셀 x, 픽셀 y. 배열은 어떨까요? 어떻게 접근 할 수 있습니까? 아니면 32 비트를 사용해야합니까? 그 많은 질문에 대해 미안하지만, 나는 방금 시작했다 – kkkkk

+0

등록 사용과 경제. 빈번하게 액세스되지 않는 레지스터를 쌓아서 대체 사용을 위해 해제하십시오. –

답변

0
 mov di, T34 
     mov si, 8 
;------------------------------------ 
P1: mov bp, 8 
;---------------- 
P2: cmp BYTE[di], 1 
     jnz short NOHIT 

     ; save used REGISTER 
     ; load register with the X,Y position and color 
     call putpixel 
     ; get back the saved Register 

NOHIT: ; increase the x position 
     inc di ; increase offset address of array 
     dec bp ; decrease counter and set zeroflag if register is zero 
     jnz P2 ; jump if zeroflag is not set 
;------------- 
     ; increase the y position + substract 8 from x position 
     dec si 
     jnz P1 
;------------------------------------ 

그것을 카운터를 증가시키기 위해 0을 갖는 루프에 대한 카운터를 시작할 수도 있지만, 0에서 8까지의 루프를 실행하려면 비교 명령이 필요합니다. 배열 내부의 오프셋 주소 카운터와 관계없이 독립적으로 지정됩니다.

조금 수정하면 코드 및 두 번째 호출에 추가 점프 명령을 넣어) 배열의 바이트가 0 인 경우 검정 픽셀을 설정할 수도 있습니다.하지만이 중첩 루프의 간단한 형태는 처음에는 이해하기가 더 쉽다고 생각합니다.

편집 : 이제 NASM과 호환됩니다.


Edit2가 : 어쩌면, X를 저장하는 것이 더 간단하다 Y는 많은 수정과 파라미터가 사용되면, 내부 루프 재 장전을 위해 공지 된 RAM 위치로 조정한다.

우리의 램 위치 :

Color DB ? ; define byte 
X_Pos DW ? ; define word 
Y_Pos DW ? 
메모리 위치에 액세스하는 방법을 보여 할

예 (기본 세그먼트는 DS입니다) :

mov [X_Pos], ax 
mov [X_Pos], bx 
mov [Color], dl 
mov ax, [X_Pos] 
mov bx, [Y_Pos] 
mov dl, [Color] 

mov WORD[X_Pos], 10 
inc WORD[X_Pos] 
sub WORD[X_Pos], 8 
mov BYTE[Color], 4 
inc BYTE[Color] 

EDIT3 :

mov dl, ax; here is error, here I set the colour 

8 비트 r을 혼합 할 수 없습니다 16 비트 레지스터를 갖는 아이리스터. 참고 :

AX = AL+AH 
DX = DL+DH 

기존 명령은 다음과 같습니다

mov dl, al 
mov dl, ah 
mov dx, ax 
movzx dl, ax 
+0

이 줄 : mov di, OFFSET T34 및 다음과 같습니다. P2 : cmp BYTE PTR [di], 1은 sth가 피연산자 다음에 있어야 함을 나타냅니다. 나는 이유를 모른다. 그래서 나는 그것을 컴파일 할 수 없었다. 나는 nasm 16 DOS를 사용한다. – kkkkk

+0

NASM의 경우 "OFFSET"을 제거하고 "PTR"을 제거합니다 (MASM에만 해당). –

+0

좋은 Y와 X입니까? mov ax, si; Y \t mov bx, bp; X 언어 C에서 'i'와 'j'를 좋아합니까? – kkkkk