-
Notifications
You must be signed in to change notification settings - Fork 0
/
say-hello-to-x86_64-assembly-part-7.html
327 lines (269 loc) · 17.2 KB
/
say-hello-to-x86_64-assembly-part-7.html
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
<!DOCTYPE html>
<html lang="en" prefix="og: http://ogp.me/ns# fb: https://www.facebook.com/2008/fbml">
<head>
<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Tangerine">
<title>Say hello to x86_64 Assembly [part 7] - Just a Memo</title>
<!-- Using the latest rendering mode for IE -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="./extra/favicon.ico" rel="icon">
<link rel="canonical" href="./say-hello-to-x86_64-assembly-part-7.html">
<meta name="author" content="Alexander Kuleshov" />
<meta name="keywords" content="linux,x86_64,assembler" />
<meta name="description" content="It is seventh part of Say hello to x86_64 Assembly and here we will look on how we can use C together with assembler. Actually we have 3 ways to use it together: Call assembly routines from C code Call c routines from assembly code Use inline assembly in C ..." />
<meta property="og:site_name" content="Just a Memo" />
<meta property="og:type" content="article"/>
<meta property="og:title" content="Say hello to x86_64 Assembly [part 7]"/>
<meta property="og:url" content="./say-hello-to-x86_64-assembly-part-7.html"/>
<meta property="og:description" content="It is seventh part of Say hello to x86_64 Assembly and here we will look on how we can use C together with assembler. Actually we have 3 ways to use it together: Call assembly routines from C code Call c routines from assembly code Use inline assembly in C ..."/>
<meta property="article:published_time" content="2014-10-10" />
<meta property="article:tag" content="linux" />
<meta property="article:tag" content="x86_64" />
<meta property="article:tag" content="assembler" />
<meta property="article:author" content="Alexander Kuleshov" />
<!-- Bootstrap -->
<link rel="stylesheet" href="./theme/css/bootstrap.min.css" type="text/css"/>
<link href="./theme/css/font-awesome.min.css" rel="stylesheet">
<link href="./theme/css/pygments/monokai.css" rel="stylesheet">
<link rel="stylesheet" href="./theme/css/style.css" type="text/css"/>
<link href="./feeds/all.atom.xml" type="application/atom+xml" rel="alternate"
title="Just a Memo ATOM Feed"/>
</head>
<body>
<div class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a href="./" style="color: sienna; font-family: 'Droid Sans'; font-size: 25px;" class="navbar-brand">
Just a Memo </a>
</div>
<div class="collapse navbar-collapse navbar-ex1-collapse">
<ul class="nav navbar-nav">
</ul>
<ul class="nav navbar-nav navbar-right">
<li>
<a href="https://twitter.com/0xAX" style="" class="navbar-brand">
<img src="extra/twitter-24.gif" width=""/>
</a>
</li>
<li>
<a href="https://github.com/0xAX" style="" class="navbar-brand">
<img src="extra/github-8-24.gif" width=""/>
</a>
</li>
<li>
<a href="https://kz.linkedin.com/in/alexander-kuleshov-301b7824"
style="" class="navbar-brand">
<img src="extra/linkedin-3-24.jpg" width=""/>
</a>
</li>
<li>
<a href="http://stackoverflow.com/users/274299/0xax" style="" class="navbar-brand">
<img src="extra/stackoverflow-24.jpg" width=""/>
</a>
</li>
<li>
<a href="http://0xax.github.io/atom" style="" class="navbar-brand">
<img src="extra/rss-24.gif" width=""/>
</a>
</li>
<li>
<a href="mailto:kuleshovmail@gmail.com" class="navbar-brand">
<img src="extra/email-12-24.gif" width=""/>
</a>
</li>
<li>
<a href="./archives.html" class="navbar-brand">
<img src="extra/archive-2-24.gif" width=""/>
</a>
</li>
</ul>
</div>
<!-- /.navbar-collapse -->
</div>
</div> <!-- /.navbar -->
<!-- Banner -->
<!-- End Banner -->
<div class="container">
<div class="row">
<div class="col-lg-12">
<section id="content">
<article>
<header style="color: #A0522D;" class="page-header">
<h1 style="color: #A0522D;">
<a href="./say-hello-to-x86_64-assembly-part-7.html"
rel="bookmark" style="color: #A0522D;"
title="Permalink to Say hello to x86_64 Assembly [part 7]">
Say hello to x86_64 Assembly [part 7]
</a>
</h1>
</header>
<div class="entry-content" style="font-family: 'Droid Sans'; font-size: 17px;">
<p>It is seventh part of Say hello to x86_64 Assembly and here we will look on how we can use C together with assembler.</p>
<p>Actually we have 3 ways to use it together:</p>
<ul>
<li>Call assembly routines from C code</li>
<li>Call c routines from assembly code</li>
<li>Use inline assembly in C code</li>
</ul>
<p>Let's write 3 simple Hello world programs which shows us how to use assembly and C together.</p>
<h2>Call assembly from C</h2>
<p>First of all let's write simple C program like this:</p>
<div class="highlight"><pre><span class="cp">#include <string.h></span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
<span class="kt">char</span><span class="o">*</span> <span class="n">str</span> <span class="o">=</span> <span class="s">"Hello World</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">len</span> <span class="o">=</span> <span class="n">strlen</span><span class="p">(</span><span class="n">str</span><span class="p">);</span>
<span class="n">printHelloWorld</span><span class="p">(</span><span class="n">str</span><span class="p">,</span> <span class="n">len</span><span class="p">);</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
<p>Here we can see C code which defines two variables: our Hello world string which we will write to stdout and length of this string. Next we call printHelloWorld assembly function with this 2 variables as parameters. As we use x86_64 Linux, we must know x86_64 linux calling convetions, so we will know how to write printHelloWorld function, how to get incoming parameters and etc... When we call function first six parameters passes through rdi, rsi, rdx, rcx, r8 and r9 general purpose registers, all another through the stack. So we can get first and second parameter from rdi and rsi registers and call write syscall and than return from function with ret instruction:</p>
<div class="highlight"><pre>global printHelloWorld
section .text
printHelloWorld:
;; 1 arg
mov r10, rdi
;; 2 arg
mov r11, rsi
;; call write syscall
mov rax, 1
mov rdi, 1
mov rsi, r10
mov rdx, r11
syscall
ret
</pre></div>
<p>Now we can build it with:</p>
<div class="highlight"><pre><span class="n">build</span><span class="o">:</span>
<span class="n">nasm</span> <span class="o">-</span><span class="n">f</span> <span class="n">elf64</span> <span class="o">-</span><span class="n">o</span> <span class="n">casm</span><span class="o">.</span><span class="na">o</span> <span class="n">casm</span><span class="o">.</span><span class="na">asm</span>
<span class="n">gcc</span> <span class="n">casm</span><span class="o">.</span><span class="na">o</span> <span class="n">casm</span><span class="o">.</span><span class="na">c</span> <span class="o">-</span><span class="n">o</span> <span class="n">casm</span>
</pre></div>
<h2>Inline assembly</h2>
<p>The following method is to write assembly code directly in C code. There is special syntax for this. It has general view:</p>
<div class="highlight"><pre>asm [volatile] ("assembly code" : output operand : input operand : clobbers);
</pre></div>
<p>As we can read in gcc documentation volatile keyword means:</p>
<div class="highlight"><pre>The typical use of Extended asm statements is to manipulate input values to produce output values. However, your asm statements may also produce side effects. If so, you may need to use the volatile qualifier to disable certain optimizations
</pre></div>
<p>Each operand is described by constraint string followed by C expression in parentheses. There are a number of constraints:</p>
<ul>
<li><code>r</code> - Kept variable value in general purpose register</li>
<li><code>g</code> - Any register, memory or immediate integer operand is allowed, except for registers that are not general registers.</li>
<li><code>f</code> - Floating point register</li>
<li><code>m</code> - A memory operand is allowed, with any kind of address that the machine supports in general.</li>
<li>and etc...</li>
</ul>
<p>So our hello world will be:</p>
<div class="highlight"><pre><span class="cp">#include <string.h></span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
<span class="kt">char</span><span class="o">*</span> <span class="n">str</span> <span class="o">=</span> <span class="s">"Hello World</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
<span class="kt">long</span> <span class="n">len</span> <span class="o">=</span> <span class="n">strlen</span><span class="p">(</span><span class="n">str</span><span class="p">);</span>
<span class="kt">int</span> <span class="n">ret</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">__asm__</span><span class="p">(</span><span class="s">"movq $1, %%rax </span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"movq $1, %%rdi </span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"movq %1, %%rsi </span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"movl %2, %%edx </span><span class="se">\n\t</span><span class="s">"</span>
<span class="s">"syscall"</span>
<span class="o">:</span> <span class="s">"=g"</span><span class="p">(</span><span class="n">ret</span><span class="p">)</span>
<span class="o">:</span> <span class="s">"g"</span><span class="p">(</span><span class="n">str</span><span class="p">),</span> <span class="s">"g"</span> <span class="p">(</span><span class="n">len</span><span class="p">));</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
<p>Here we can see the same 2 variables as in previous example and inline assembly definition. First of all we put 1 to rax and rdi registers (write system call number, and stdout) as we did it in our plain assembly hello world. Next we do similar operation with rsi and rdi registers but first operands starts with % symbol instead $. It means str is the output operand referred by %1 and len second output operand referred by %2, so we put values of str and len to rsi and rdi with %n notation, where n is number of output operand. Also there is %% prefixed to the register name.</p>
<div class="highlight"><pre> This helps GCC to distinguish between the operands and registers. operands have a single % as prefix
</pre></div>
<p>We can build it with:</p>
<div class="highlight"><pre><span class="n">build</span><span class="o">:</span>
<span class="n">gcc</span> <span class="n">casm</span><span class="o">.</span><span class="na">c</span> <span class="o">-</span><span class="n">o</span> <span class="n">casm</span>
</pre></div>
<h2>Call C from assembly</h2>
<p>And the last method is to call C function from assembly code. For example we have following simple C code with one function which just prints Hello world:</p>
<div class="highlight"><pre><span class="cp">#include <stdio.h></span>
<span class="k">extern</span> <span class="kt">int</span> <span class="nf">print</span><span class="p">();</span>
<span class="kt">int</span> <span class="nf">print</span><span class="p">()</span> <span class="p">{</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"Hello World</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
<p>Now we can define this function as extern in our assembly code and call it with call instruction as we do it much times in previous posts:</p>
<div class="highlight"><pre>global _start
extern print
section .text
_start:
call print
mov rax, 60
mov rdi, 0
syscall
</pre></div>
<p>Build it with:</p>
<div class="highlight"><pre><span class="n">build</span><span class="o">:</span>
<span class="n">gcc</span> <span class="o">-</span><span class="n">c</span> <span class="n">casm</span><span class="o">.</span><span class="na">c</span> <span class="o">-</span><span class="n">o</span> <span class="n">c</span><span class="o">.</span><span class="na">o</span>
<span class="n">nasm</span> <span class="o">-</span><span class="n">f</span> <span class="n">elf64</span> <span class="n">casm</span><span class="o">.</span><span class="na">asm</span> <span class="o">-</span><span class="n">o</span> <span class="n">casm</span><span class="o">.</span><span class="na">o</span>
<span class="n">ld</span> <span class="o">-</span><span class="kd">dynamic</span><span class="o">-</span><span class="n">linker</span> <span class="sr">/lib64/</span><span class="n">ld</span><span class="o">-</span><span class="n">linux</span><span class="o">-</span><span class="n">x86</span><span class="o">-</span><span class="mi">64</span><span class="o">.</span><span class="na">so</span><span class="o">.</span><span class="mi">2</span> <span class="o">-</span><span class="n">lc</span> <span class="n">casm</span><span class="o">.</span><span class="na">o</span> <span class="n">c</span><span class="o">.</span><span class="na">o</span> <span class="o">-</span><span class="n">o</span> <span class="n">casm</span>
</pre></div>
<p>and now we can run our third hello world.</p>
</div>
<!-- /.entry-content -->
<div class="panel" style="font-family: 'Droid Sans';">
<div class="panel-body" style="">
<hr style="margin-left: -15px;"/>
<!-- AddThis Button BEGIN -->
<div class="addthis_toolbox addthis_default_style" style="margin-left: -15px;">
<a class="addthis_button_facebook_like" fb:like:layout="button_count"></a>
<a class="addthis_button_tweet"></a>
<a class="addthis_button_google_plusone" g:plusone:size="medium"></a>
<div style="float: right;"><footer class="post-info">
<span class="label label-default">Date</span>
<span class="published">
<i style="top: -1px; position: relative; margin-top: -1px;" class="fa fa-calendar"></i>
<time datetime="2014-10-10T00:00:00+07:00"> Fri 10 October 2014</time>
</span>
</footer><!-- /.post-info --></div>
</div>
<!-- AddThis Button END -->
</div>
</div>
</article>
</section>
</div>
</div>
</div>
<footer>
<div class="container">
<div class="row">
<div class="col-xs-12" style="float: left;"> <p style="float: right;"><small> <a style="color: #a0522d; float: right;" href="https://github.com/0xAX">@0xAX © 2016</a>
</small></p>
</div>
</div>
</div>
</footer>
<script src="./theme/js/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="./theme/js/bootstrap.min.js"></script>
<!-- Enable responsive features in IE8 with Respond.js (https://github.com/scottjehl/Respond) -->
<script src="./theme/js/respond.min.js"></script>
<!-- Google Analytics -->
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-64079379-1']);
_gaq.push(['_trackPageview']);
(function () {
var ga = document.createElement('script');
ga.type = 'text/javascript';
ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ga, s);
})();
</script>
<!-- End Google Analytics Code -->
<script type="text/javascript">var addthis_config = {"data_track_addressbar": true};</script>
<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-53a535f822555b0c"></script>
</body>
</html>