-
Notifications
You must be signed in to change notification settings - Fork 0
/
print_integer.S
107 lines (87 loc) · 1.76 KB
/
print_integer.S
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# Prints an int to stdin, formatted as a base-10 number
.global _start
.global _print_integer
.set write_code,1
.set exit_code,60
.set zero_offset,48
.data
newline_buffer: .ascii "\n"
.bss
.lcomm digit,1
.text
/*
Following are several lines of code used in the testing of this program
_start:
# Print the int backwards to start
# Registers: rax : syscall/divident
# rbx : base
# rdx : divident tail (ie value to print)
pushq $9191
call _print
mov $60,%rax
mov $0,%rdi
syscall # exit(0)
*/
_print_integer:
# _print is a wrapper around print_actual that preserves the values of all
# registers. This should ease its use in debugging, where I might not
# wish to go to the effort of saving several registers
push %rax
push %rbx
push %rsp
push %rdx
push %r15
push %rsi
push %rdi
movq 0x40(%rsp),%rax
push %rax
call print_actual
pop %rax
pop %rdi
pop %rsi
pop %r15
pop %rdx
pop %rsp
pop %rbx
pop %rax
ret
print_actual:
# --------
# return address
# number to print in decimal
mov $10,%rbx # Print in base 10
movq 0x8(%rsp),%rax # Load the value to print from the stack
# rbx : base
# rax : value
xor %rdx,%rdx # 0 extend rax:rdx
divq %rbx # quotient -> rax, remainder -> rdx
push %rdx
push %rax
cmp $0,%rax
je print_digit
# ------
# remaining value
# current digit
# return address
# previous value
# previous digit
call print_actual
print_digit:
pop %r15
call print_single_digit
pop %r15
ret
print_single_digit:
# The top of the stack here should have
# --------
# address to return to
# digit to print
movb 0x8(%rsp),%al # Get the digit from the stack
add $48,%al # Convert the digit to ascii
mov %al,digit
mov $1,%rax # write()
mov $1,%rdi # stdout
mov $digit, %rsi # buf
mov $1,%rdx # len
syscall
ret