Skip to content

Instantly share code, notes, and snippets.

@diamondburned
Last active October 19, 2022 21:30
Show Gist options
  • Save diamondburned/2a21f4cf3a610624ce1c18490d9e24c4 to your computer and use it in GitHub Desktop.
Save diamondburned/2a21f4cf3a610624ce1c18490d9e24c4 to your computer and use it in GitHub Desktop.
atod implementation in x86 nasm compiled from C
// This code is taken from StackOverflow. Code taken from StackOverflow are
// licensed under CC BY-SA 3.0. See
// https://creativecommons.org/licenses/by-sa/3.0/ for more information.
//
// Source Link: https://stackoverflow.com/a/4392789/5041327
// atod converts a string to a double.
double atod(const char *s) {
double rez = 0, fact = 1;
if (*s == '-') {
s++;
fact = -1;
};
for (int point_seen = 0; *s; s++) {
if (*s == '.') {
point_seen = 1;
continue;
};
int d = *s - '0';
if (d >= 0 && d <= 9) {
if (point_seen)
fact /= 10.0f;
rez = rez * 10.0f + (double)d;
};
};
return rez * fact;
};
; This code is taken from StackOverflow. Code taken from StackOverflow are
; licensed under CC BY-SA 3.0. See
; https://creativecommons.org/licenses/by-sa/3.0/ for more information.
;
; Source Link: https://stackoverflow.com/a/4392789/5041327
; atod converts a string to a double.
global atod
section .text
atod:
cmp byte [rdi], 45
movsd xmm1, qword [rel LC1]
jnz ?_001
movsd xmm1, qword [rel LC0]
inc rdi
?_001:
movsd xmm2, qword [rel LC3]
xor edx, edx
xorps xmm0, xmm0
?_002:
movsx eax, byte [rdi]
test al, al
jz ?_006
cmp al, 46
jz ?_004
sub eax, 48
cmp eax, 9
ja ?_005
test edx, edx
jz ?_003
divsd xmm1, xmm2
?_003:
mulsd xmm0, xmm2
cvtsi2sd xmm3, eax
addsd xmm0, xmm3
jmp ?_005
?_004:
mov edx, 1
?_005:
inc rdi
jmp ?_002
?_006:
mulsd xmm0, xmm1
ret
section .data
section .bss
section .rodata
LC0:
dq 0BFF0000000000000H
LC1:
dq 3FF0000000000000H
LC3:
dq 4024000000000000H
atod.asm: _atod.c
gcc -Wall -Os -s -c ./_atod.c
objconv -fnasm _atod.o
# Sanitize the output.
dos2unix _atod.asm
sed -i \
-e 's/;.*$$//' \
-e 's/\.\(LC[0-9]*\)/\1/g' \
-e 's/^default rel//g' \
-e 's/^SECTION \(\.\w*\).*$$/section \1/g' \
-e 's/^global \(\w*\):.*$$/global \1/g' \
-e 's/^section \.\(note\|eh_frame\)//g' \
-e 's/ *\(db\|dd\) .*//g' \
-e 's/^\([^ ]*\):\(.*\)$$/\1:\n\2/g' \
_atod.asm
command -v nasmfmt &> /dev/null && nasmfmt _atod.asm
# Transfer the comments over.
cat _atod.c \
| sed -n '/\(\/\/\|^$$\)/p' \
| sed -e 's/\/\//;/' -e 's/^;$$/; /g' \
> _atod.cmt
# Merge the comments into the assembly.
cat _atod.cmt _atod.asm > atod.asm
# Tidy and format.
rm _atod.cmt _atod.asm
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment