Skip to content

Instantly share code, notes, and snippets.

@giuscri
Last active October 1, 2015 16:24
Show Gist options
  • Save giuscri/b790fb581bce4490831a to your computer and use it in GitHub Desktop.
Save giuscri/b790fb581bce4490831a to your computer and use it in GitHub Desktop.
## main.s
## !, assemble and link it (on x86_64) via
## $ as --32 --gstabs main.s -o main.o
## $ ld -m elf_i386 main.o -o main
.section .text
.global _start
__atoi:
### int __atoi (const char * buf, size_t buf_length)
### Convert a string to an integer.
pushl %ebp
movl %esp, %ebp
## Make room for the integer n
subl $4, %esp
## Load buf into %ecx
movl 8(%ebp), %ecx
1:
## Initialize %ebx to 0
xorl %ebx, %ebx
## Load the first byte @%ecx into %ebx
movb (%ecx), %bl
## If < 0x30 ('0'), break loop
cmpl $0x30, %ebx
jl 2f
## If > 0x39 ('9'), break loop
cmpl $0x39, %ebx
jg 2f
## Load the integer n into %eax ...
movl -4(%ebp), %eax
## ... multiply it by 10
movl $10, %edx
mull %edx
## %ebx =- '0' ...
subl $0x30, %ebx
## ... and add it to %eax
addl %ebx, %eax
## Thus load it as the integer n
movl %eax, -4(%ebp)
## Move the ptr to the next byte
incl %ecx
## Continue
jmp 1b
2:
## Load the integer n into %eax and return
movl -4(%ebp), %eax
addl $4, %esp
popl %ebp
ret
__itoa:
### void __itoa (int n, const char * buf, size_t buf_length)
## Convert an integer to a string
pushl %ebp
movl %esp, %ebp
1:
## Move the integer n into %ebx
movl 8(%ebp), %ebx
## If <= 0, break the loop
cmpl $0, %ebx
jle 2f
## %eax, %edx = 0, 0
xorl %eax, %eax
xorl %edx, %edx
## Divide n by 10
movl 8(%ebp), %eax
movl $10, %ebx
divl %ebx
## Move the result as the new n
movl %eax, 8(%ebp)
## While shift right (that is, left: little endian!)
## the old pattern @buf by 1 byte ...
movl 12(%ebp), %ebx
movl (%ebx), %ebx
shl $8, %ebx
## ... and add 0x30 to n%10, such to
## have it as an ascii character
addl $0x30, %edx
orl %edx, %ebx
movl 12(%ebp), %ecx
movl %ebx, (%ecx)
## Continue
jmp 1b
2:
## Just return
popl %ebp
ret
_start:
## Inizialize the pattern @buf to zero
xorl %ebx, %ebx
movl $buf, %ecx
movl %ebx, (%ecx)
## sys_write(1, lbra, lbra_length)
movl $lbra_length, %edx
movl $lbra, %ecx
movl $1, %ebx
movl $4, %eax
int $0x80
## sys_read(0, buf, buf_length)
movl $buf_length, %edx
movl $buf, %ecx
movl $0, %ebx
movl $3, %eax
int $0x80
pushl $buf_length
pushl $buf
call __atoi
## number_1 = __atoi(buf, buf_length)
movl $number_1, %ebx
movl %eax, (%ebx)
## Inizialize the pattern @buf to zero
xorl %ebx, %ebx
movl $buf, %ecx
movl %ebx, (%ecx)
## sys_write(1, lbra, lbra_length)
movl $lbra_length, %edx
movl $lbra, %ecx
movl $1, %ebx
movl $4, %eax
int $0x80
## sys_read(0, buf, buf_length)
movl $buf_length, %edx
movl $buf, %ecx
movl $0, %ebx
movl $3, %eax
int $0x80
pushl $buf_length
pushl $buf
call __atoi
## number_1 = __atoi(buf, buf_length)
movl $number_2, %ebx
movl %eax, (%ebx)
## result = number_1 - number_2
movl $number_1, %ebx
movl (%ebx), %ebx
movl $number_2, %edx
movl (%edx), %edx
subl %edx, %ebx
movl $result, %edx
movl %ebx, (%edx)
## Inizialize the pattern @buf to zero
xorl %ebx, %ebx
movl $buf, %ecx
movl %ebx, (%ecx)
## __itoa(result, buf, buf_length)
pushl $buf_length
pushl $buf
movl $result, %ecx
pushl (%ecx)
call __itoa
## sys_write(1, rbra, rbra_length)
movl $rbra_length, %edx
movl $rbra, %ecx
movl $1, %ebx
movl $4, %eax
int $0x80
## sys_write(1, buf, buf_length)
movl $buf_length, %edx
movl $buf, %ecx
movl $1, %ebx
movl $4, %eax
int $0x80
## sys_write(1, nl, 2)
movl $2, %edx
movl $nl, %ecx
movl $1, %ebx
movl $4, %eax
int $0x80
exit:
movl $0, %ebx
movl $1, %eax
int $0x80
.section .data
buf:
.byte 0x0, 0x0, 0x0, 0x0
buf_length = . - buf
nl:
.ascii "\n\0"
lbra:
.ascii "> \0"
lbra_length = . - lbra
rbra:
.ascii "< \0"
rbra_length = . - rbra
number_1:
.long 0x0
number_2:
.long 0x0
result:
.long 0x0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment