오늘 짠 어셈블리의 끝판왕.

생각보다 atoi를 어셈블리로 짜려고 하니까 여간 힘든게 아니다.

프로그래밍을 하면서 알고리즘이나 자료구조 등을 제대로 공부하지 않아서인지는 모르지만 더 좋은 길도 잘 떠오르지 않았고...

결국 엄청 더러우면서도 작동은 하는 소스가 만들어졌다.

해당 프로그램은 stdin으로 숫자를 입력받아 해당 수만큼 반복하여 "Hello World"를 puts해주는 기능을 가졌다.

만약 숫자가 아닌 값을 입력하면 "It is Not Number!"를 출력하고 종료된다.

많이 조잡하지만 만들고 나니 뿌듯하긴 하다.


.globl main
main:
	push %ebp
	mov %esp, %ebp
	sub $0x04, %esp
	lea -0x04(%ebp), %ecx
	push %ecx
	call gets
	lea -0x04(%ebp), %eax
	push %eax
	call atoi
	mov %eax, %esi
	xor %edi, %edi
	.main_loop:
		cmp %edi, %esi
		jle .main_finish
		push $helloworld
		call puts
		inc %edi
		jmp .main_loop
	.main_finish:
		leave
		ret

atoi:
	push %ebp
	mov %esp, %ebp
	mov 0x08(%ebp), %esi
	push %esi
	call isNumberStr
	cmp $0x00, %eax
	jle .atoi_notNumber
	mov 0x08(%ebp), %esi
	push %esi
	call strlen
	mov %eax, %edi
	xor %eax, %eax
	mov 0x08(%ebp), %esi
	xor %ecx, %ecx
	xor %edx, %edx
	.atoi_loop:
		xor %ebx, %ebx
		movb (%esi), %bl
		cmpb $0x00, %bl
		je .atoi_finish
		cmp $0x00, %edi
		je .atoi_finish
		sub $0x30, %bl
		mov %edi, %ecx
		.atoi_loop2:
			cmp $0x01, %ecx
			je .atoi_add
			imul $0x0a, %ebx
			dec %ecx
			jmp .atoi_loop2
			.atoi_add:
				add %ebx, %eax
				inc %esi
				dec %edi
				jmp .atoi_loop
	.atoi_notNumber:
		push $notNumber
		call puts
		mov $-0x01, %eax
		jmp .atoi_finish
	.atoi_finish:
		leave
		ret


gets:
	push %ebp
	mov %esp, %ebp
	sub $0x1000, %esp
	mov $0x03, %eax
	mov $0x00, %ebx
	lea -0x1000(%ebp), %ecx
	mov $0x1000, %edx
	int $0x80
	lea -0x1000(%ebp), %eax
	push $0x0a
	push %eax
	call strchr
	movb $0x00, (%eax)
	lea -0x1000(%ebp), %eax
	push %eax
	mov 0x08(%ebp), %eax
	push %eax
	call strcpy
	leave
	ret

isAlpha:
	push %ebp
	mov %esp, %ebp
	xor %eax, %eax
	movb 0x08(%ebp), %al
	movb %al, %bl
	cmpb $0x41, %al
	jl .isAlpha_notalpha
	cmpb $0x5a, %al
	jng .isAlpha_alpha
	cmpb $0x61, %al
	jl .isAlpha_notalpha
	cmpb $0x7a, %al
	jng .isAlpha_alpha
	jmp .isAlpha_notalpha
	.isAlpha_alpha:
		mov $0x01, %eax
		jmp .isAlpha_finish
	.isAlpha_notalpha:
		mov $-0x01, %eax
		jmp .isAlpha_finish
	.isAlpha_finish:
		leave
		ret

isNumber:
	push %ebp
	mov %esp, %ebp
	xor %eax, %eax
	movb 0x08(%ebp), %al
	cmpb $0x30, %al
	jl .isNumber_notnumber
	cmpb $0x39, %al
	jng .isNumber_number
	jmp .isNumber_notnumber
	.isNumber_number:
		mov $0x01, %eax
		jmp .isNumber_finish
	.isNumber_notnumber:
		mov $-0x01, %eax
		jmp .isNumber_finish
	.isNumber_finish:
		leave
		ret

isAlphaStr:
	push %ebp
	mov %esp, %ebp
	xor %ebx, %ebx
	mov 0x08(%ebp), %esi
	.isAlphaStr_loop:
		movb (%esi), %bl
		and $0xff, %ebx
		cmpb $0x00, %bl
		je .isAlphaStr_Alpha
		push %ebx
		call isAlpha
		cmpb $0x00, %al
		jl .isAlphaStr_notAlpha
		inc %esi
		jmp .isAlphaStr_loop
	.isAlphaStr_Alpha:
		mov $0x01, %eax
		jmp .isAlphaStr_finish
	.isAlphaStr_notAlpha:
		mov $-0x01, %eax
		jmp .isAlphaStr_finish
	.isAlphaStr_finish:
		leave
		ret

isNumberStr:
	push %ebp
	mov %esp, %ebp
	xor %ebx, %ebx
        mov 0x08(%ebp), %esi
        .isNumberStr_loop:
                movb (%esi), %bl
                and $0xff, %ebx
                cmpb $0x00, %bl
                je .isNumberStr_Number
                push %ebx
                call isNumber
                cmpb $0x00, %al
                jl .isNumberStr_notNumber
                inc %esi
                jmp .isNumberStr_loop
        .isNumberStr_Number:
                mov $0x01, %eax
                jmp .isNumberStr_finish
        .isNumberStr_notNumber:
                mov $-0x01, %eax
                jmp .isNumberStr_finish
        .isNumberStr_finish:
                leave
                ret
	leave
	ret

puts:
	push %ebp
	mov %esp, %ebp
	mov 0x08(%ebp), %eax
	push %eax
	call strlen
	mov %eax, %edx
	mov $0x04, %eax
	mov $0x01, %ebx
	mov 0x08(%ebp), %ecx
	int $0x80
	push $0x0a
	lea (%esp), %ecx
	mov $0x04, %eax
	mov $0x01, %ebx
	mov $0x01, %edx
	int $0x80
	add $0x04, %esp
	leave
	ret

strcpy:
	push %ebp
	mov %esp, %ebp
	xor %eax, %eax
	mov 0x08(%ebp), %edi
	mov 0x0c(%ebp), %esi
	.strcpy_loop:
		movb (%esi), %al
		movb %al, (%edi)
		cmpb $0x00, %al
		je .strcpy_finish
		inc %esi
                inc %edi
		jmp .strcpy_loop
	.strcpy_finish:
		leave
		ret


strlen:
	push %ebp
	mov %esp, %ebp
	xor %ecx, %ecx
	mov 0x08(%ebp), %eax
	.strlen_loop:
		movb (%eax), %bl
		cmpb $0x00, %bl
		je .strlen_finish
		inc %eax
		inc %ecx
		jmp .strlen_loop
	.strlen_finish:
		mov %ecx, %eax
		leave
		ret

notNumber : .string "It is Not Number!"
helloworld : .string "Hello, World"


'Programming' 카테고리의 다른 글

파이썬 웹 이미지 크롤러 (GUI)  (0) 2016.02.03
[C++] 가상함수(Virtual Function)  (0) 2016.01.20
Assembly Programming - isAlpha, isNumber  (0) 2015.10.11
Assembly Programming - gets  (0) 2015.10.10
Assembly Programming - strchr  (0) 2015.10.10
블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

,