사용자로부터 2byte 의 10진수를 입력받고 입력받은수를 2진수로 출력하라.

 

바로 nasm으로 적어보려고했으나 잘안되서 c로 먼저 굴려봤습니다.

#include <stdio.h>

int main(int argc, const char * argv[]) {
    int target = 0;
    int remain[100] = {0,};
    int index = 0;
    scanf("%d",&target);
    while (target > 1) {
        remain[index] = target % 2;
        target = target / 2;
        index++;
    }
    printf("%d\n",target);
    for (int i = index - 1; i >= 0; i--) {
        printf("%d\n", remain[i]);
    }
    return 0;
}

이렇게나 간단한건데

속이 터지네요

 

 

계속 문제가 생기는  mov eax, dword [target] 부분을

and eax, 0x0000ffff 추가로 땜빵해줬습니다...

필요한 부분은 ax뿐만이라(2byte수 제한) 솔직히 앞부분은 필요없기도하고........

 

누가좀 알려줬으면 좋겠네요

 

%include "io64.inc"

 

section .text

global CMAIN

CMAIN:

mov rbp, rsp; for correct debugging

GET_DEC 2, ax

mov [target], ax

L_loop:

mov eax, 0

mov edx, 0

 

mov eax, dword [target]

and eax, 0x0000ffff

 

mov edx, eax

shr edx, 16

and eax, 0x0000ffff

 

mov ebx, 0

mov bx, 2

div bx

 

mov ebx, [remainder_index]

mov [remainder + ebx * 2], dx

add [remainder_index], word 1

 

mov [target], ax

cmp ax, 1

jle L_loop_end

jmp L_loop

L_loop_end:

;print

PRINT_DEC 2, target

;NEWLINE

 

mov eax, 0

mov eax, [remainder_index]

dec eax

 

L_print_loop:

PRINT_DEC 2, [remainder + eax * 2]

;NEWLINE

add [print_count], word 1

 

dec ax

mov bx, [print_count]

cmp bx, [remainder_index]

je L_end

jmp L_print_loop

L_end:

xor rax,rax

ret

section .bss

target resw 1

remainder resw 100

section .data

remainder_index dw 0

print_count dw 0

'NASM' 카테고리의 다른 글

9일차  (0) 2020.06.23
8일차.  (0) 2020.06.21
7일차.  (0) 2020.06.20
6일차.  (0) 2020.06.19
5일차.  (0) 2020.06.18

1~ 입력받은 수(2byte)까지의 3의 배수를 구하고 그 수를 출력, 합을 출력

 

%include "io64.inc"

 

section .text

global CMAIN

CMAIN:

mov rbp, rsp; for correct debugging

GET_DEC 2, input

 

L_loop:

add [for_index],word 1 ; 반복 인덱스값 증가

 

;인덱스값이 3의 배수인지 판별하려고 3으로나눠봄

mov eax, [for_index]

;dx에 전반부 ax에 후반부로 나눠야 계산이됨 - 실제 저장된건 리틀엔디안 스타일이기에 값으로는 반대

mov edx, eax

shr edx, 16

 

and eax, 0x0000ffff

 

mov bx, 3

div bx ; 값은 ax에 몫, dx에 나머지가 저장됨

 

cmp dx, 0 ; 나머지가 0인지 판별하려고함

jne L_after_save ;0이 아니라면 데이터배열에 저장하지않음

 

;데이터배열에 저장

mov eax, 0

mov ax, [data_index]

mov bx, [for_index]

mov [data + eax * 2], bx

inc ax

mov [data_index], ax

 

L_after_save:

mov bx, [for_index]

cmp bx, [input]

jne L_loop; for_index가 입력된 값과 같을때까지 반복

 

; 저장된 값 출력

PRINT_STRING str_print_start

mov eax, 0

L_print_loop:

;3의 배수값 출력 + 합구하기

mov dx, [data + eax * 2]

add [total], dx

PRINT_DEC 2, dx

PRINT_STRING str_comma_space

 

inc ax

 

mov bx, [data_index]

cmp ax, bx

jne L_print_loop

 

NEWLINE

;저장된 개수

PRINT_STRING str_count

PRINT_DEC 2, [data_index]

NEWLINE

;합

PRINT_STRING str_total

PRINT_DEC 2, [total]

NEWLINE

 

xor rax, rax

ret

 

section .bss

data resw 100

input resw 1

section .data

data_index dw 0

for_index dw 0

total dw 0

;msg

str_print_start db '3의 배수 : ',0x00

str_comma_space db ', ',0x00

str_count db '3의 배수 갯수 : ',0x00

str_total db '총합 : ',0x00

 

2byte수를 한 개 입력 받아(10진수) 이 숫자를 2진수로 출력하라

막혔음... 

c로 하면 간단한데 어디서 문제가 생긴지 모르겠다.

 

 

 

 

'NASM' 카테고리의 다른 글

10일차.  (0) 2020.06.24
8일차.  (0) 2020.06.21
7일차.  (0) 2020.06.20
6일차.  (0) 2020.06.19
5일차.  (0) 2020.06.18

배열 복사...  디버깅 테스트용

디버깅 메뉴에서 show memory 에 들어가면 각 변수별 관찰이 가능하다.

변수이름을 적고 타입을 정하면 실행시 자동으로 값이 보임

주소값으로도 볼 수 있는데 왼쪽의 address를 꼭 체크해야 된다.

%include "io64.inc"

 

section .text

global CMAIN

CMAIN:

;write your code here

mov eax, my1

mov ebx, you1

 

mov edx, 0

mov ecx, 3

 

L1:

mov eax, [my1 + edx * 2]

mov [you1 + edx * 2], eax

inc edx

loop L1

 

mov edx, 0

L2:

PRINT_HEX 2, my1 + edx * 2

NEWLINE

inc edx

cmp edx, 3

jl L2

 

xor rax, rax

ret

 

section .data

my1 dw 0x1234, 0x4567, 10

 

section .bss

you1 resw 3

4- 문제

2바이트 수 한개를 입력받고 1 ~ 입력받은수 까지의 3의 배수만 배열에 저장하고 그 개수와 값을 출력

 

풀다가 못풀었음.; 내일로 미룸

'NASM' 카테고리의 다른 글

10일차.  (0) 2020.06.24
9일차  (0) 2020.06.23
7일차.  (0) 2020.06.20
6일차.  (0) 2020.06.19
5일차.  (0) 2020.06.18

반복문

 

%inlucde "io64.inc"

section .text

global CMAIN

CMAIN:

;write your code here

mov ax, 0

mov ecx, 10

 

L_loop:

add ax, cx

loop L_loop

 

PRINT_DEC 2, ax

NEWLINE

 

xor rax, rax

ret

 

inc,  1증가

 

%include "io64.inc"

 

section .text

global CMAIN

CMAIN:

;write your code here

mov ax,0

mov bx,1

mov cx,10

L_L1:

add ax,bx

inc bx

loop L_L1

 

PRINT_DEC 2, ax

NEWLINE

 

xor rax, rax

ret

 

 

 

do while

 

%include "io64.inc"

 

section .text

global CMAIN

CMAIN:

;write your code here

mov ax,0

mov bx,0

L1:

add ax, bx

inc bx

cmp bx, 10

jle L1

 

PRINT_DEC 2,ax

NEWLINE

xor rax, rax

ret

 

 

while

 

%include "io64.inc"

 

section .text

global CMAIN

CMAIN:

;write your code here

mov ax,0

mov bx,0

L1:

cmp bx, 10

jg L2

add ax, bx

inc bx

jmp L1

L2:

PRINT_DEC 2, ax

NEWLINE

xor rax, rax

ret

 

 

배열 접근하기 

 

include "io64.inc"

 

section .text

global CMAIN

CMAIN:

;write your code here

mov al, [a]

PRINT_DEC 1, al

NEWLINE

 

mov al, [a+1]; a는 1바이트 크기

PRINT_DEC 1, al

NEWLINE

 

mov ax, [b]

PRINT_HEX 2, ax

NEWLINE

 

mov ax, [b + 1 * 2]

PRINT_HEX 2, ax

NEWLINE

 

mov ax, [b + 2 * 2]

PRINT_DEC 2, ax

NEWLINE

 

xor rax, rax

ret

 

section .data

a db 30,50,60

b dw 0x1234, 0x5678, 10

 

배열 복사.

포인트는 괄호 내부안에 들어가는 레지스터 변수는 무조건 4바이트 변수로 넣을것 밑에 보면 인덱스를 굳이 eax로 한 이유임 

include "io64.inc"

 

section .text

global CMAIN

CMAIN:

;write your code here

mov eax, 0

mov ecx, 3

 

L1:

mov ebx,[origin + eax * 2]; eax에 인덱스값을 저장 2바이트크기 변수임

mov [copy + eax * 2], ebx

inc eax

loop L1

 

mov edx, copy;edx에 copy시작주소를 넣음.. 왜?

mov eax, 0

L2:

PRINT_HEX 2, [edx + eax * 2]

NEWLINE

inc eax

cmp eax,3

jl L2

 

xor rax, rax

ret

 

section .data

origin dw 0x1234,0x4567, 0x8912

section .bss

copy resw 3

 

 

'NASM' 카테고리의 다른 글

9일차  (0) 2020.06.23
8일차.  (0) 2020.06.21
6일차.  (0) 2020.06.19
5일차.  (0) 2020.06.18
4일차.  (0) 2020.06.17

1. 2byte 세숫자를 입력받고, 가장큰수, 가장작은수를 메모리에 저장하라

2. 가장큰값과 가장작읍값의 곱을 출력하라.

%include ""io64.inc"
section .text
global CMAIN
CMAIN:
    ;write your code here
    
    ;input
    GET_DEC 2, input_a
    GET_DEC 2, input_b
    GET_DEC 2, input_c

    ; input_a, input_b를 비교
    mov ax, [input_a]
    mov bx, [input_b]

    cmp ax, bx
    jg L_great_ax; ax>bx 가 참이면 이동
    
    ;ax<=bx 이면 실행 
    mov [max], bx
    mov [min], ax
    
    jmp L_max_next_step

L_great_ax:
    mov [max], ax
    mov [min], bx

;처음 비교 끝
L_max_next_step:;최종 최대값 구하기 max 와 c값 비교
    mov ax, [max]
    mov bx, [input_c]
    cmp ax, bx
    jg L_find_max_end; max > input_c 이미 맥스가 구해진 상태 엔드로 이동
    mov [max], bx
;max를 찾음
L_find_max_end:
    ;가장 작은수를 구하자
    mov ax, [min]
    mov bx, [input_c]

    cmp ax, bx
    jl L_find_min_end; min이 이미 제일 작음
    mov [min], bx

L_find_min_end:
    ;최소와 최대값의 곱을 출력해야함 2byte애들임
    mov edx, 0
    mov eax, 0

    mov ax, [max]
    mov bx, [min]

    mul bx ; dx:ax = ax * bx
    shl edx, 16 ;4칸 왼쪽으로(16진수)
    and eax, 0x0000ffff ; 뒤 네칸만 남기고 0으로 설정
    or eax,edx
    mov [total], eax

    ;출력
    PRINT_STRING str_max
    PRINT_DEC 2,max
    NEWLINE

    PRINT_STRING str_min
    PRINT_DEC 2,min
    NEWLINE

    PRINT_STRING str_mul_max_n_min
    PRINT_DEC 4, total
    NEWLINE

    xor rax, rax
    ret
section .bss
    input_a resw 1
    input_b resw 1
    input_c resw 1
    max resw 1
    min resw 1
    total resd 1
section .data
    str_max db 'max : ', 0x00
    str_min db 'min : ', 0x00
    str_mul_max_n_min db 'max*min = ', 0x00

 

 

. 사용자 입력으로 수를 입력받아 3의 배수인지 출력하라

문제에 범위가 적혀있지않아 배운부분으로 적당히 해봄

 

include "io64.inc"

 

section .text

global CMAIN

CMAIN:

;write your code here

GET_DEC 2, input_a

 

;피제수를 두개로 나누고....

mov eax, [input_a]

mov edx, eax

shr edx, 16; 앞 4개만 남기고...

and eax, 0x0000ffff ; 뒤 4개만 남기고...

 

mov bx, 3

div bx ; ax = quotient, dx = remainder

 

cmp dx, word 0

jne L_not_equal

PRINT_STRING str_equal

jmp L_end

L_not_equal:

PRINT_STRING str_not_equal

L_end:

xor rax, rax

ret

section .bss

input_a resw 1

 

section .data

str_equal db '배수이다.',0x00

str_not_equal db '아니다',0x00

 

 

dx:ax값을 ebx로 이동하는 알고리즘을 만들기, shift연산은 사용하지말고 메모리와 mov연산만으로 구현

. 못풀었음.;; 내일 조금 다시 해보다 안되면 질문좀 올려봐야할거같음 

 

'NASM' 카테고리의 다른 글

8일차.  (0) 2020.06.21
7일차.  (0) 2020.06.20
5일차.  (0) 2020.06.18
4일차.  (0) 2020.06.17
3일차.  (0) 2020.06.17

나누기 2바이트 이상

 

%include "io64.inc"

 

section .text

global CMAIN

CMAIN:

;write your code here

mov eax, 0x12345678 ;305419896

mov bx, 0x4567 ;17767

 

mov edx, eax

shr edx, 16

and eax, 0x0000ffff

div bx

mov [quotient], ax

mov [remainder], dx

 

PRINT_HEX 2, quotient

NEWLINE

PRINT_DEC 2, quotient

NEWLINE

PRINT_HEX 2, remainder

NEWLINE

PRINT_DEC 2, remainder

NEWLINE

 

xor rax, rax

ret

section .bss

quotient resw 1

remainder resw 1

 

TEST매크로 zf설정 관찰하기

 

%include "io64.inc"

 

section .text

global CMAIN

CMAIN:

mov rbp, rsp; for correct debugging

;write your code here

 

mov ax, 0x1234

and ax, 0x0000; zf설정됨 ax값도 변경됨

PRINT_HEX 2, ax

NEWLINE

 

add ax, 0x1234; zf가 설정된게 풀어짐

mov ax, 0x1234

test ax,0x0000; zf값은 설정되나 ax값은 변경안됨

PRINT_HEX 2, ax

NEWLINE

 

 

xor rax, rax

ret

 

 

 if문의 구현,  cmp와 jmp이용

je : 같다면 

%include "io64.inc"

 

section .text

global CMAIN

CMAIN:

;write your code here

mov ax, 20

mov bx, 10

 

cmp ax,bx ;ax 와 bx를 비교연산을 할것이다.

je L_equal ; ax와bx가 같다면 L_equal 라벨로 이동 하라

mov cx, 0 ; 위 라인의 je가 실행이 안됐다면 실행됨, ax와bx가 다름

jmp L_equal_end ;무조건 L_eqaul_end로 이동 goto문인듯

 

L_equal:

mov cx, 100

 

L_equal_end:

PRINT_DEC 2,cx

NEWLINE

 

xor rax, rax

ret

 

 

위와 같은 기능을 하나 순서를 다르게한 소스

%include "io64.inc"

 

section .text

global CMAIN

CMAIN:

;write your code here

mov ax, 20

mov bx, 10

 

cmp ax,bx

je L_equal

jmp L_not_equal

L_equal:

mov cx, 100

jmp L_eqaul_end

L_not_equal:

mov cx, 0

L_eqaul_end:

PRINT_DEC 2, cx

 

xor rax, rax

ret

 

위와 같은 기능을 하나 또다른 소스 jne로 jne:같지 않다면

%include "io64.inc"

 

section .text

global CMAIN

CMAIN:

;write your code here

mov ax,20

mov bx,10

 

cmp ax,bx

jne L_not_equal

 

;ax bx 같다면

mov cx, 100

jmp L_not_equal_end

L_not_equal:

mov cx, 0

L_not_equal_end:

PRINT_HEX 2, cx

 

xor rax, rax

ret

 

'NASM' 카테고리의 다른 글

7일차.  (0) 2020.06.20
6일차.  (0) 2020.06.19
4일차.  (0) 2020.06.17
3일차.  (0) 2020.06.17
2일차  (0) 2020.06.15

3일차에 마지막에 했던 예제문제, 

그 소스는 버리고 그냥 처음부터 다시 쳤다.

아직도 거기서 뭐가 문제였는지 모르겠음.

 

%include "io64.inc"

 

section .text

global CMAIN

CMAIN:

mov rbp, rsp; for correct debugging

;write your code here

mov ax, 0

mov bx, 0

 

;input

GET_DEC 1, al

GET_DEC 1, bl

 

mov [input_a], al

mov [input_b], bl

 

PRINT_DEC 1, input_a

PRINT_STRING str_space

PRINT_DEC 1, input_b

NEWLINE

 

;add

add al,bl

mov [result_add], al

 

 

;sub

mov al, [input_a]

sub al,bl

mov [result_sub], al

 

 

 

;mul

mov ax, 0

mov al, [input_a]

mul bx

mov [result_mul], ax

 

 

;div

mov ax,0

mov bx,0

 

mov al, [input_a];ax에 넣어서 계싼하면 오류는 안뜨나 뒤에 가 작동안함... 왜그런지 모르겠다.

mov bl, [input_b]

 

div bl

mov [result_div_quotient], al

mov bl, ah

mov [result_div_remainder], bl

 

 

;print

PRINT_STRING str_add

PRINT_DEC 1, result_add

NEWLINE

PRINT_STRING str_sub

PRINT_DEC 1, result_sub

NEWLINE

PRINT_STRING str_mul

PRINT_DEC 2, result_mul

NEWLINE

PRINT_STRING str_div_quotient

PRINT_DEC 1, result_div_quotient

NEWLINE

PRINT_STRING str_div_remainder

PRINT_DEC 1, result_div_remainder

NEWLINE

 

xor rax, rax

ret

 

section .bss

input_a resb 1

input_b resb 1

 

result_add resb 1

result_sub resb 1

result_mul resw 1

result_div_quotient resb 1

result_div_remainder resb 1

section .data

str_space db ' ',0x00

str_add db 'add : ',0x00

str_sub db 'sub : ',0x00

str_mul db 'mul : ',0x00

str_div_quotient db 'div-quotient : ',0x00

str_div_remainder db 'div-remainder : ',0x00

 

 

div연산이 2일차인가에 했던 예제랑 좀 다름

al,ah = ax / para (al에 몫, ah에 나머지)

여서 ax에 피제수를 넣고 para에 제수를 넣었는데

이상하게 ax에 피제수를 넣고 돌리면 프로그램이 멈춘다.

al에 피제수를 넣고 돌리면 ok~

이유는 모르겠음

 

 

 

shift 연산

 

section .text

global CMAIN

CMAIN:

;write your code here

mov ax, 0x1234

 

PRINT_HEX 2, ax

NEWLINE

 

shl ax,4

 

PRINT_HEX 2, ax

NEWLINE

 

mov [a], word 0x1234

PRINT_HEX 2, a

NEWLINE

 

shr word [a], 4 ; 메모리 변수의 크기를 말해주지않으면 에러...

PRINT_HEX 2,a

NEWLINE

 

 

xor rax, rax

ret

 

section .bss

a resw 1

 

and, or, xor, not 연산

include "io64.inc"

 

section .text

global CMAIN

CMAIN:

;write your code here

mov al, [target_a];0xb6

mov bl, 0b01010101; 0x55

 

;and

and al,bl

PRINT_HEX 1,al

NEWLINE

 

;or

mov al,[target_a]

or al,bl

PRINT_HEX 1,al

NEWLINE

;xor

mov al, [target_a]

xor al,bl

PRINT_HEX 1, al

NEWLINE

 

;not

mov al, [target_a]

not al

PRINT_HEX 1, al

NEWLINE

 

xor rax, rax

ret

 

section .data

target_a db 0b10110110; 0xb6 0b는 이진수

 

 

 

 

2byte 곱연산

%include "io64.inc"

 

section .text

global CMAIN

CMAIN:

;write your code here

;mov edx, 0

;mov eax, 0

 

mov ax, 0x2710;10000(10)

mov bx, 0x1388;5000(10)

 

mul bx ; dx:ax = ax*bx

shl edx, 16; dx에 이미 상위값이 들어가있다. 들어가기전에 왜 edx를0 으로 초기화를 안해주는걸까.?

and eax, 0x0000ffff;edx와 마찬가지로 ax에 하위값이 들어가있다.

or eax,edx

 

mov [result], eax

PRINT_HEX 4,result

NEWLINE

PRINT_DEC 4,result

NEWLINE

 

 

xor rax, rax

ret

 

section .bss

result resd 1

 

 

슬슬 소스좀 정리해서  깃에 넣어놔야할것 같음

'NASM' 카테고리의 다른 글

6일차.  (0) 2020.06.19
5일차.  (0) 2020.06.18
3일차.  (0) 2020.06.17
2일차  (0) 2020.06.15
1일차.  (0) 2020.06.14

nasm 에서 입력받는 매크로 10진

GET_DEC 바이트수, 주소

 

%include "io64.inc"

 

section .text

global CMAIN

CMAIN:

;write your code here

GET_DEC 1, al

GET_DEC 2,a

 

PRINT_DEC 1,al

NEWLINE

PRINT_DEC 2, a

 

xor rax, rax

ret

 

 

section .bss

a resw 1

 

 

 

곱하기

 

%include "io64.inc"

 

section .text

global CMAIN

CMAIN:

;write your code here

PRINT_DEC 2, ax

NEWLINE

 

mov ax, 0

mov al, 2

mov bl, 4

 

PRINT_DEC 1, bx

NEWLINE

 

mul bx

 

PRINT_DEC 1, ax

NEWLINE

 

xor rax, rax

ret

 

 

나누기

%include "io64.inc"

 

section .text

global CMAIN

CMAIN:

;write your code here

 

;7/2

 

mov ax, 7

mov bl, 2

div bl

 

mov bl, ah ; ah == 나머지값

 

PRINT_DEC 1, al

NEWLINE

 

PRINT_DEC 1, bl

NEWLINE

 

xor rax, rax

ret

 

곱하고 나누고

 

%include "io64.inc"

 

section .text

global CMAIN

CMAIN:

mov rbp, rsp; for correct debugging

;

mov ax, 0

mov al, 2

mov bl, 3

mul bx

 

PRINT_DEC 1, ax

NEWLINE

 

mov ax, 7

mov bl, 2

div bl

mov bl, ah

 

PRINT_DEC 1, al

NEWLINE

PRINT_DEC 1, bl

NEWLINE

 

xor rax, rax

ret

 

 

 

연습문제

2개의 변수를 사용자로부터 1byte단위로 입력받아 메모리에 저장하고 더하고, 빼고 , 곱하고 나눈값을 메모리에 각각 개별적으로 저장후 출력하라.

안돌아감... 틀린답.

고치는건 4일차에하자

더보기

%include "io64.io"
section .text
global CMAIN
CMAIN:
    ;write your code here
    
    GET_DEC 1, al
    GET_DEC 1, bl
    
    mov [input_a], al
    mov [input_b], bl

    add al, bl
    mov [result_add], al
    PRINT_STRING msg_result_add
    PRINT_DEC 1,result_add
    NEWLINE
    
    mov al, [input_a]
    sub al, bl
    mov [result_sub], al
    PRINT_STRING msg_result_sub
    PRINT_DEC 1, result_sub
    NEWLINE
    
    mov ax, 0
    mov al, input_a
    mul bl
    mov [result_mul], ax
    PRINT_STRING msg_result_mul
    PRINT_DEC 2, result_mul
    NEWLINE
    
    mov ax, [input_a]
    div bl
    mov [result_div_quotient], al
    mov [result_div_remainder], ah
    PRINT_STRING msg_result_div
    PRINT_STRING msg_open_bracket
    PRINT_DEC 1, result_div_quotient
    PRINT_STRING msg_slash
    PRINT_DEC 1, result_div_remainder
    PRINT_STRING msg_close_bracket
    
     
    
    xor rax, rax
    ret
    
section .bss
input_a resb 1
input_b resb 1
result_add resb 1
result_sub resb 1
result_mul resw 1
result_div_quotient resb 1
result_div_remainder resb 1

section .data
msg_result_add db 'add : ',0x00
msg_result_sub db 'sub : ',0x00
msg_result_mul db 'mul : ',0x00
msg_result_div db 'div[quotient/remainder] : ',0x00
msg_open_bracket db '[',0x00
msg_close_bracket db ']',0x00
msg_slash db '/',0x00

 

'NASM' 카테고리의 다른 글

6일차.  (0) 2020.06.19
5일차.  (0) 2020.06.18
4일차.  (0) 2020.06.17
2일차  (0) 2020.06.15
1일차.  (0) 2020.06.14

+ Recent posts