Programming/Assembly

어셈블리어 - add/sub, mul, div

lee308812 2021. 3. 13. 15:18

[ SAMS 툴에서 숫자 입력/출력하기 ]

- [Help] - [Help]에서 방법을 찾아보면

- 레지스터나 변수에 사용자로부터 부호있는 10진수를 입력받기 위해서 GET_DEC를 사용하면 된다는 것을 알 수 있다.

- 부호있는 10진수 데이터 출력은 PRINT_DEC임을 알 수 있다.


[ Add/Sub : Carry를 포함하지 않는 덧셈/뺄셈 ]

- a는 레지스터 또는 메모리

- b는 레지스터 또는 메모리 또는 상수

- 주의) a,b가 둘다 메모리이면 안된다.

 

Q) 레지스터 A에 1byte를 입력받고, 초기화 되지 않은 전역변수 B에 1byte를 입력받아 A + B를 계산하는 프로그램을 작성하시오.

%include "io64.inc"

section .text
global CMAIN
CMAIN:
    ;write your code here
    GET_DEC 1, al ; A레지스터의 1byte영역에 1byte만큼 10진수 입력 받음.
    GET_DEC 1, b  ; 변수 b에 1byte만큼 10진수 입력 받음.
    
    add al, [b]   ; ★ []를 쓰지 않으면 b의 주소값이 됨에 유의
    PRINT_DEC 1, al
   
    xor rax, rax
    ret
    
section .data

    
section .bss
    b resb 1

 

- 주의] 메모리 + 상수를 할 때, 레지스터를 쓸 때(rax, eax 등) 처럼 크기를 알 수 있는 정보가 아무것도 없으므로 반드시 크기를 지정해 줘야함에 유의한다.

add [b], 1          ; Error
add [b], byte 1     ; OK

 

- Sub는 Add와 덧셈/뺄셈 차이만 있을뿐 똑같다.

 


[ Mul ]

- b는 레지스터 또는 메모리

%include "io64.inc"

section .text
global CMAIN
CMAIN:
    mov rbp, rsp; for correct debugging
    ;write your code here
    
    ; rax, rdx에 이상한 값으로 채운다.
    mov rax, 0x1234567812345678
    mov rdx, 0x1234567812345678
    
    mov al, 0xFF
    mov bl, 0xFF
    
    ; 0xFF x 0xFF = 0xFE01
    mul bl
    
    PRINT_HEX 8, rdx
    NEWLINE
    PRINT_HEX 8, rax
    
    xor rax, rax
    ret
    

 

- 대상을 메모리로 지정할 경우, 크기를 지정해줘야함에 유의하자.

%include "io64.inc"

section .text
global CMAIN
CMAIN:
    mov rbp, rsp; for correct debugging
    ;write your code here
    
    ; rax, rdx에 이상한 값으로 채운다.
    mov rax, 0x1234567812345678
    mov rdx, 0x1234567812345678
    
    mov rax, 0xFFFFFFFFFFFFFFFF
    mov qword [b], qword 0x1000
    
    ; 0xFFFFFFFFFFFFFFFF x 0x1000
    mul qword [b]
    
    PRINT_HEX 8, rdx
    NEWLINE
    PRINT_HEX 8, rax
    
    xor rax, rax
    ret
    
section .bss
    b resq 1

 

 

[ div ]

- 일단은 간단하게 정리하고 추가.