<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Leandro Proença</title>
    <description>The latest articles on DEV Community by Leandro Proença (@leandronsp).</description>
    <link>https://dev.to/leandronsp</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F29160%2F7682c138-1242-4179-add4-9a810e9afafd.jpeg</url>
      <title>DEV Community: Leandro Proença</title>
      <link>https://dev.to/leandronsp</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/leandronsp"/>
    <language>en</language>
    <item>
      <title>Taming non-determinism: from logic gates to LLMs</title>
      <dc:creator>Leandro Proença</dc:creator>
      <pubDate>Thu, 19 Feb 2026 03:47:38 +0000</pubDate>
      <link>https://dev.to/leandronsp/taming-non-determinism-from-logic-gates-to-llms-3mf0</link>
      <guid>https://dev.to/leandronsp/taming-non-determinism-from-logic-gates-to-llms-3mf0</guid>
      <description>&lt;p&gt;Or: &lt;em&gt;how engineering keeps turning chaos into reliable computation. And why agentic AI still hasn't solved this.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There's a pattern that repeats across the entire history of computing: we take something fundamentally &lt;strong&gt;non-deterministic&lt;/strong&gt; and engineer enough layers on top of it until it behaves deterministically. Logic gates did it. Artificial neural networks (ANNs) replicated it at some level. LLMs are the next frontier, and the hardest one yet.&lt;/p&gt;

&lt;p&gt;In this article, we'll explore how engineering is crucial to facing non-determinism, and analyse the current state of the art for LLMs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Agenda
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
Part I - The lie inside a logic gate

&lt;ul&gt;
&lt;li&gt;Noise margins&lt;/li&gt;
&lt;li&gt;The CPU clock&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Part II - Aspirina: teaching non-determinism to behave

&lt;ul&gt;
&lt;li&gt;Where the chaos lives&lt;/li&gt;
&lt;li&gt;Composition does the rest&lt;/li&gt;
&lt;li&gt;The cost compared&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Part III - LLMs and the "Unresolved Problem"

&lt;ul&gt;
&lt;li&gt;Tests as noise margins&lt;/li&gt;
&lt;li&gt;The agentic loop as clock&lt;/li&gt;
&lt;li&gt;The type system and compiler&lt;/li&gt;
&lt;li&gt;What's missing: timing analysis&lt;/li&gt;
&lt;li&gt;How to mitigate that?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Conclusion&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  Part I - The lie inside a logic gate
&lt;/h2&gt;

&lt;p&gt;A &lt;a href="https://en.wikipedia.org/wiki/Logic_gate" rel="noopener noreferrer"&gt;logic gate&lt;/a&gt; is taught in school as a simple binary machine. You give it 0s and 1s, you get 0s and 1s back. &lt;/p&gt;

&lt;p&gt;AND, OR and XOR are example of logic gates. They are clean, mathematical, deterministic. And that's a useful &lt;em&gt;fiction&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;At the physical level, a gate is a transistor (or a few of them) through which electrons flow. Electrons don't care about your &lt;strong&gt;Boolean algebra&lt;/strong&gt;. The voltage on a wire is a continuous, analog value that fluctuates due to thermal noise, manufacturing variance, electromagnetic interference, and even cosmic radiation flipping bits in memory.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Fun fact: in May 2003, in Belgium, an electronic voting machine gave a candidate &lt;a href="https://en.wikipedia.org/wiki/Electronic_voting_in_Belgium" rel="noopener noreferrer"&gt;exactly 4096 extra votes&lt;/a&gt;. More than she could possibly have received. After investigation, the error was attributed to the &lt;strong&gt;spontaneous creation of a 13th bit in the memory of the computer&lt;/strong&gt;. The leading explanation: a cosmic ray flipped a single bit, turning a 0 into a 1 at position 2^12, adding exactly 4096 to the candidate count.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ok, but how does the industry get determinism out of this mess?&lt;/p&gt;

&lt;h3&gt;
  
  
  Noise margins
&lt;/h3&gt;

&lt;p&gt;Engineers define voltage thresholds: anything below 0.8V is a &lt;code&gt;0&lt;/code&gt;, anything above 2.0V is a &lt;code&gt;1&lt;/code&gt;. The zone between those values is declared "forbidden". The circuit is designed to never operate stably there. This isn't physics; it's an engineering contract. (&lt;a href="https://en.wikipedia.org/wiki/Noise_margin" rel="noopener noreferrer"&gt;More on noise margins&lt;/a&gt;)&lt;/p&gt;

&lt;h3&gt;
  
  
  The CPU clock
&lt;/h3&gt;

&lt;p&gt;A CPU clock isn't just a metronome. It's also a &lt;em&gt;sampling strategy&lt;/em&gt;. You let the signal propagate through the gate (which takes time, called &lt;strong&gt;propagation delay&lt;/strong&gt;), and only read the value at a specific moment: the &lt;em&gt;clock edge&lt;/em&gt;. By then, the signal has had time to cross the threshold and stabilise. Timing is calculated to guarantee this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But when timing fails, things may get weird&lt;/strong&gt;. If a signal is sampled while it's still in the forbidden zone, a flip-flop can enter &lt;a href="https://en.wikipedia.org/wiki/Metastability_(electronics)" rel="noopener noreferrer"&gt;metastability&lt;/a&gt;, which is an unstable equilibrium where the output isn't quite &lt;code&gt;0&lt;/code&gt; or &lt;code&gt;1&lt;/code&gt; and can oscillate for an indeterminate time. This may cause real crashes in real systems. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Think of metastability as what happens when two clocks on a wall are unsynchronized. Each showing a slightly different time. "What time is it right now?", one may ask. The answer depends on which clock you look at, but you can't decide which one is right.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Inside the CPU, when facing a forbidden zone, the flip-flop faces the same dilemma. It can't decide if it's a &lt;code&gt;0&lt;/code&gt; or a &lt;code&gt;1&lt;/code&gt;, which can corrupt the system state. Engineers mitigate this with synchronizer chains, but never eliminate it entirely.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;It's the non-determinism of physics leaking through the engineering abstraction&lt;/em&gt;!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The key insight&lt;/strong&gt;: the determinism of digital computing is not a property of nature. It's an &lt;em&gt;engineering achievement&lt;/em&gt;. It's paid with noise margins, timing analysis and careful design.&lt;/p&gt;

&lt;p&gt;Yes, it's all about &lt;strong&gt;engineering&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part II - Aspirina: teaching non-determinism to behave
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/leandronsp/aspirina" rel="noopener noreferrer"&gt;Aspirina&lt;/a&gt; is my personal project that builds a complete CPU entirely from artificial neural networks (ANNs) trained to behave as logic gates, written in Rust. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Actually I created the &lt;a href="https://github.com/leandronsp/morphine" rel="noopener noreferrer"&gt;very first version&lt;/a&gt; almost 10 years ago in Elixir, when I was learning about ANNs and Elixir. Recently I decided to write a Rust version while I was learning Rust. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The inversion from Part I brings the beauty: instead of physical electrons that need to be tamed into bits, here we have ANNs - &lt;em&gt;systems whose weights are initialised randomly and whose outputs are continuous floating-point numbers&lt;/em&gt; - that need to be tamed into &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;1&lt;/code&gt; too.&lt;/p&gt;

&lt;p&gt;The non-determinism here is introduced deliberately, and then engineered away. Bear with me.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where the chaos lives - unleash the madness
&lt;/h3&gt;

&lt;p&gt;A neural network starts with random weights. Its output for any input is whatever the math happens to produce. Not &lt;code&gt;0&lt;/code&gt;, not &lt;code&gt;1&lt;/code&gt;, but something like &lt;code&gt;0.6312&lt;/code&gt;. In case you missed, I already have an article in my blog about &lt;a href="https://leandronsp.com/articles/ai-ruby-an-introduction-to-neural-networks-23f3" rel="noopener noreferrer"&gt;neural networks&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Backpropagation is the engineering response&lt;/strong&gt;. It's the algorithm that adjusts the weights iteratively, measuring how wrong the output is (the &lt;em&gt;loss&lt;/em&gt;) and leading weights in the direction that reduces the error. Run this for 10,000 epochs - 10,000 passes over the training data - and the network converges to weights that produce &lt;code&gt;0.002&lt;/code&gt; for inputs that should be &lt;code&gt;0&lt;/code&gt;, and &lt;code&gt;0.997&lt;/code&gt; for inputs that should be &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://en.wikipedia.org/wiki/Sigmoid_function" rel="noopener noreferrer"&gt;sigmoid function&lt;/a&gt; (a.k.a the &lt;em&gt;logistic curve&lt;/em&gt;) does in Aspirina what noise margins do in hardware: it squashes any continuous value into the range &lt;code&gt;0..1&lt;/code&gt;. It doesn't give you exact binary outputs, but it pushes values toward the extremes.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;And that's exactly what we need&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Combined with a threshold decision - below &lt;code&gt;0.5&lt;/code&gt; we could consider &lt;code&gt;0&lt;/code&gt;, above &lt;code&gt;0.5&lt;/code&gt; we consider &lt;code&gt;1&lt;/code&gt; -, we get in Aspirina the same effect: a circuit that &lt;em&gt;behaves deterministically&lt;/em&gt; even though its internals are continuous and learned.&lt;/p&gt;

&lt;h3&gt;
  
  
  Composition does the rest
&lt;/h3&gt;

&lt;p&gt;Once gates are trained, they're composed to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;XOR + AND =&amp;gt; Half Adder =&amp;gt; Full Adder =&amp;gt; 4-bit ALU =&amp;gt; Memory =&amp;gt; Registers =&amp;gt; CPU =&amp;gt; Assembler =&amp;gt; Interpreter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each layer treats the layer below as if it were perfectly deterministic, which is &lt;strong&gt;exactly the abstraction hierarchy&lt;/strong&gt; of real hardware.&lt;/p&gt;

&lt;p&gt;The non-determinism was contained at the lowest level (training), and every layer above it benefits from the illusion of determinism. &lt;/p&gt;

&lt;p&gt;Yes, &lt;strong&gt;determinism is an illusion&lt;/strong&gt;. Deal with it.&lt;/p&gt;

&lt;h3&gt;
  
  
  The cost compared
&lt;/h3&gt;

&lt;p&gt;Compute time during training. Just as chip fabrication invests energy upfront to create reliable silicon, Aspirina invests 10,000 epochs upfront to create reliable logic. After that, inference is cheap and stable.&lt;/p&gt;

&lt;p&gt;Now, &lt;em&gt;enter LLMs&lt;/em&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part III - LLMs and the "Unresolved Problem"
&lt;/h2&gt;

&lt;p&gt;A &lt;a href="https://en.wikipedia.org/wiki/Large_language_model" rel="noopener noreferrer"&gt;large language model&lt;/a&gt; (LLM) is non-deterministic in a deeper and more stubborn way than either of the above.&lt;/p&gt;

&lt;p&gt;Its weights are the result of a stochastic training process over vast data. Its output is sampled probabilistically (even with &lt;code&gt;temperature=0&lt;/code&gt;), and there's pseudo-randomness baked in. And crucially, unlike a neural network trained on a clean truth table, an LLM's "correct output" for most inputs is &lt;em&gt;fundamentally ambiguous&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Yet we're building agentic systems (Claude Code, Codex, Cursor etc) that use LLMs to write, run and iterate on code autonomously. &lt;strong&gt;How do we tame this?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The pattern repeats, but the engineering is particularly &lt;em&gt;messier&lt;/em&gt; on LLM's.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tests as noise margins
&lt;/h3&gt;

&lt;p&gt;A test suite could behave as a binary verdict on the LLM's  output: &lt;em&gt;green or red&lt;/em&gt;. It doesn't matter if the model generated three different valid implementations in three runs: if all tests pass, they're equivalent from the system's perspective. The non-determinism of the model is &lt;em&gt;contained&lt;/em&gt; below the threshold of "passes tests". This works, but only as well as the tests themselves. And unlike voltage thresholds, test coverage is always incomplete.&lt;/p&gt;

&lt;h3&gt;
  
  
  The agentic loop as clock
&lt;/h3&gt;

&lt;p&gt;An agentic system like Claude Code doesn't generate once and deliver. It reads state (files, compiler output, test results), acts, observes the new state, and repeats. This feedback loop is structurally similar to the &lt;em&gt;fetch-decode-execute&lt;/em&gt; cycle of a CPU or the iterative of Aspirina. Each iteration constrains the space of valid next actions. Errors are observable, and the agent can correct.&lt;/p&gt;

&lt;h3&gt;
  
  
  The type system and compiler as low-level validators
&lt;/h3&gt;

&lt;p&gt;In a Rust project like Aspirina, the borrow checker &lt;em&gt;rejects invalid outputs before tests even run&lt;/em&gt;. &lt;em&gt;The LLM can generate wrong code and hallucinate, the compiler then refuses it, the agent observes the error message, and iterates.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is a lower-level noise margin&lt;/strong&gt;: just a formal filter beneath the test layer and type system. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;And that's why I think that languages with strict compilers like Rust will thrive in the agentic era. Let's see.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  What's missing: the equivalent of timing analysis
&lt;/h3&gt;

&lt;p&gt;In hardware, engineers can &lt;em&gt;prove&lt;/em&gt; that a circuit will work at a given clock frequency. They run static timing analysis and guarantee that every signal stabilises before every clock edge. There's no equivalent for agentic LLM systems.&lt;/p&gt;

&lt;p&gt;We don't know how many iterations an agent will need. We can't bound the convergence time. We can't guarantee termination. An agent can loop indefinitely, or enter what I'd call "agentic metastability": making and undoing the same change repeatedly, unable to reach a stable state.&lt;/p&gt;

&lt;p&gt;Anyone who has used Claude Code or Codex for long enough has seen this - the model oscillates between two approaches, each creating a problem that motivates reverting to the other.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Despite we can retry, add guardrails, skills, and set token budgets, in the end, we can't prove termination the way a hardware engineer proves timing closure on metastability&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  How to mitigate that?
&lt;/h3&gt;

&lt;p&gt;In hardware, the fix for metastability is &lt;strong&gt;design&lt;/strong&gt;. In agentic systems, the analog fix is &lt;strong&gt;clearer context, more granular tests, explicit checkpoints and tighter feedback loops&lt;/strong&gt;; which can be described with the following practical list of skills I created and have been using on a daily basis for every project in production:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PO (product owner)&lt;/strong&gt;: agent receives a prompt and outputs a well-scoped task based on initial requirements and prior knowledge on the codebase. Clearer context.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TDD (test-driven development)&lt;/strong&gt;: the developer agent outputs the code, guided by TDD - red, green, refactor. Granular tests as noise margins.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review&lt;/strong&gt;: agent and human checks before merging. Explicit checkpoint.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Small PRs&lt;/strong&gt;: small PR's enable development and testing with reviewable increments. Tighter feedback loops.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yes, that's &lt;strong&gt;software engineering practices&lt;/strong&gt; all the way down (and they are not new). Yet we don't have the formal tools &lt;em&gt;to prove&lt;/em&gt; these fixes work. It's totally empirical. &lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;At least for me, what's interesting is that each level's "solved" status depends on &lt;em&gt;bounded, well-defined tasks&lt;/em&gt;. Logic gates are deterministic for Boolean logic. Aspirina's networks converge reliably because truth tables are finite and exact. LLMs work well on narrow, testable tasks with earlier and good feedback.&lt;/p&gt;

&lt;p&gt;The frontier is: &lt;strong&gt;what does it take to engineer reliable agentic behaviour on open-ended, ambiguous, long-horizon tasks?&lt;/strong&gt; The answer probably looks like what came before: more layers of verification, better sampling strategies (the clock), formal specifications (the truth table), and tools that can analyse convergence before execution. &lt;em&gt;We just don't have those yet&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Non-determinism doesn't go away. It never has. We just keep finding better ways to push it where it can't hurt us. From voltage thresholds to synchronizer chains to temperature tuning. Every generation of computing has faced the same enemy and responded with the same weapon: &lt;strong&gt;engineering&lt;/strong&gt;. Besides hype, LLMs are no different. We're just earlier in the cycle.&lt;/p&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Logic_gate" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Logic_gate&lt;/a&gt;&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Electronic_voting_in_Belgium" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Electronic_voting_in_Belgium&lt;/a&gt;&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Noise_margin" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Noise_margin&lt;/a&gt;&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Metastability_(electronics)" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Metastability_(electronics)&lt;/a&gt;&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Sigmoid_function" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Sigmoid_function&lt;/a&gt;&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Large_language_model" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Large_language_model&lt;/a&gt;&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Backpropagation" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Backpropagation&lt;/a&gt;&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Static_timing_analysis" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Static_timing_analysis&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/leandronsp/aspirina" rel="noopener noreferrer"&gt;https://github.com/leandronsp/aspirina&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/leandronsp/morphine" rel="noopener noreferrer"&gt;https://github.com/leandronsp/morphine&lt;/a&gt;&lt;br&gt;
&lt;a href="https://leandronsp.com/articles/ai-ruby-an-introduction-to-neural-networks-23f3" rel="noopener noreferrer"&gt;https://leandronsp.com/articles/ai-ruby-an-introduction-to-neural-networks-23f3&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>ann</category>
    </item>
    <item>
      <title>You don't need Kafka: Building a message queue with only two UNIX signals</title>
      <dc:creator>Leandro Proença</dc:creator>
      <pubDate>Tue, 21 Oct 2025 00:06:14 +0000</pubDate>
      <link>https://dev.to/leandronsp/you-dont-need-kafka-building-a-message-queue-with-only-two-unix-signals-4fhl</link>
      <guid>https://dev.to/leandronsp/you-dont-need-kafka-building-a-message-queue-with-only-two-unix-signals-4fhl</guid>
      <description>&lt;p&gt;Have you ever asked yourself what if we could replace any message broker with a very simple one using only two UNIX signals? Well, I'm not surprised if you didn't. But I did. And I want to share my journey of how I achieved it.&lt;/p&gt;

&lt;p&gt;If you want to learn about UNIX signals, binary operations the easy way, how a message broker works under the hood, and a bit of Ruby, this post is for you.&lt;/p&gt;

&lt;p&gt;And if you came here just because of the clickbait title, I apologize and invite you to keep reading. It'll be fun, I promise.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2y7f1m1ltect0yymkfxj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2y7f1m1ltect0yymkfxj.png" alt=" " width="800" height="317"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  It's all about UNIX
&lt;/h2&gt;

&lt;p&gt;A few days ago, I saw some discussion on the internet about how we could send messages between processes. Many people think of sockets, which are the most common way to send messages, even allowing communication across different machines and networks. Some don't even realize that pipes are another way to send messages between processes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'hello'&lt;/span&gt; | &lt;span class="nb"&gt;base64
&lt;/span&gt;aGVsbG8K
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's what's happening:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The process &lt;code&gt;echo&lt;/code&gt; is started with the content "hello"&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;echo&lt;/code&gt; is a program that prints the message to &lt;em&gt;STDOUT&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Through the pipe, the content in &lt;em&gt;STDOUT&lt;/em&gt; is &lt;strong&gt;sent&lt;/strong&gt; directly to the &lt;em&gt;STDIN&lt;/em&gt; of the &lt;code&gt;base64&lt;/code&gt; process&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;base64&lt;/code&gt; process encodes its input to Base64 and then puts the result in &lt;em&gt;STDOUT&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note the word "send". Yes, anonymous pipes are a form of &lt;strong&gt;IPC (Inter-process communication).&lt;/strong&gt; Other forms of IPC in UNIX include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;named pipes (mkfifo)&lt;/li&gt;
&lt;li&gt;sockets&lt;/li&gt;
&lt;li&gt;regular files&lt;/li&gt;
&lt;li&gt;or even a simple &lt;strong&gt;signal&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  UNIX signals
&lt;/h2&gt;

&lt;p&gt;According to &lt;a href="https://dev.tourl"&gt;Wikipedia&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A UNIX signal is a standardized message sent to a program to trigger specific behaviour, such as quitting or error handling&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are many signals we can send to a process, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SIGTERM - sends a notification to the process to terminate. It can be "trapped," which means the process can do some cleanup work before termination, like releasing OS resources and closing file descriptors&lt;/li&gt;
&lt;li&gt;SIGKILL - sends a termination signal that cannot be trapped or ignored, forcing immediate termination&lt;/li&gt;
&lt;li&gt;SIGINT - the interrupt signal, typically sent when you press &lt;code&gt;Ctrl+C&lt;/code&gt; in the terminal. It can be trapped, allowing the process to perform cleanup before exiting gracefully&lt;/li&gt;
&lt;li&gt;SIGHUP - the hangup signal, originally sent when a terminal connection was lost. Modern applications often use it to reload configuration files without restarting the process&lt;/li&gt;
&lt;li&gt;SIGQUIT - similar to SIGINT but also generates a core dump for debugging&lt;/li&gt;
&lt;li&gt;SIGSTOP - pauses (suspends) a process. Cannot be trapped or ignored&lt;/li&gt;
&lt;li&gt;SIGCONT - resumes a process that was paused by &lt;em&gt;SIGSTOP&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;SIGCHLD - sent to a parent process when a child process terminates or stops&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SIGUSR1&lt;/strong&gt; and &lt;strong&gt;SIGUSR2&lt;/strong&gt; - user-defined signals that applications can use for custom purposes&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Sending messages using  signals
&lt;/h2&gt;

&lt;p&gt;Okay, we know that signals are a primitive form of IPC. UNIX-like systems provide a syscall called &lt;code&gt;kill&lt;/code&gt; that sends signals to processes. Historically, this syscall was created solely to terminate processes. But over time, they needed to accommodate other types of signals, so they reused the same syscall for different purposes. &lt;/p&gt;

&lt;p&gt;For instance, let's create a simple Ruby script &lt;code&gt;sleeper.rb&lt;/code&gt; which sleeps for 60 seconds, nothing more:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Process ID: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pid&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Sleeping for 60 seconds..."&lt;/span&gt;
&lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After running we see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Process ID: 55402
Sleeping for 60 seconds...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In another window, we can &lt;strong&gt;send&lt;/strong&gt; the &lt;code&gt;SIGTERM&lt;/code&gt; signal to the process &lt;code&gt;55402&lt;/code&gt; via syscall &lt;code&gt;kill&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;kill&lt;/span&gt; &lt;span class="nt"&gt;-SIGTERM&lt;/span&gt; 55402
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then, in the script session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[1]    55402 terminated  ruby sleeper.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Signal traps
&lt;/h3&gt;

&lt;p&gt;In Ruby, we can also &lt;em&gt;trap&lt;/em&gt; a signal using the &lt;code&gt;trap&lt;/code&gt; method in Ruby:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Process ID: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pid&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Sleeping for 60 seconds..."&lt;/span&gt;

&lt;span class="nb"&gt;trap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'SIGTERM'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; 
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Received SIGTERM, exiting gracefully..."&lt;/span&gt;
  &lt;span class="nb"&gt;exit&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which in turn, after sending the signal, will gracefully:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Process ID: 55536
Sleeping for 60 seconds...
Received SIGTERM, exiting gracefully...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After all, we &lt;em&gt;cannot send messages using signals&lt;/em&gt;. They are a primitive way of sending &lt;em&gt;standardized messages&lt;/em&gt; which will trigger specific behaviours. At most, we can trap some signals, but nothing more.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Okay Leandro, but what's the purpose of this article then?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Hold on&lt;/em&gt;. That's exactly why I'm here. To prove points by doing useless stuff, like when I &lt;a href="https://leandronsp.com/articles/simulating-oop-in-bash-3mop" rel="noopener noreferrer"&gt;simulated OOP in Bash&lt;/a&gt; a couple of years ago (it was fun though).&lt;/p&gt;

&lt;p&gt;To understand how we can "hack" UNIX signals and send messages between processes, let's first talk a bit about &lt;strong&gt;binary operations&lt;/strong&gt;. Yes, those "zeros" and "ones" you were scared of when you saw them for the first time. But they don't bite (🥁 LOL), I promise.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a message?
&lt;/h2&gt;

&lt;p&gt;If we model a message as a sequence of characters, we could say that at a high-level, messages are simply &lt;em&gt;strings&lt;/em&gt;. But in memory, they are stored as &lt;strong&gt;bytes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We know that bytes are made of bits. In computer terms, what's a bit? It's simply an abstraction representing &lt;strong&gt;only two states&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;zero&lt;/li&gt;
&lt;li&gt;one&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's it. For instance, using &lt;a href="https://dev.tourl"&gt;ASCII&lt;/a&gt;, we know that the letter "h" has the following codes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;104 in decimal&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;0x68&lt;/code&gt; in hexadecimal&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;01101000&lt;/code&gt; in binary&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Binary-wise, what if we represented each "0" with a specific signal and each "1" with another? We know that some signals such as SIGTERM, SIGINT, and SIGCONT can be trapped, but intercepting them would harm their original purpose.&lt;/p&gt;

&lt;p&gt;But thankfully, UNIX provides two user-defined signals that are perfect for our hacking experiment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sending SIGUSR1 and SIGUSR2
&lt;/h2&gt;

&lt;p&gt;First things first, let's trap those signals in the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Process ID: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pid&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Sleeping forever. Send signals to this process to see how it responds."&lt;/span&gt;

&lt;span class="nb"&gt;trap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'SIGUSR1'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; 
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Received SIGUSR1 signal"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nb"&gt;trap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'SIGUSR2'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Received SIGUSR2 signal"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nb"&gt;sleep&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Process ID: 56172
Sleeping forever. Send signals to this process to see how it responds.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After sending some &lt;code&gt;kill -SIGUSR1 56172&lt;/code&gt; and &lt;code&gt;kill -SIGUSR2 56172&lt;/code&gt;, we can see that the process prints the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Process ID: 56172
Sleeping forever. Send signals to this process to see how it responds.
Received SIGUSR1 signal
Received SIGUSR2 signal
Received SIGUSR2 signal
Received SIGUSR1 signal
Received SIGUSR1 signal
Received SIGUSR2 signal
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Signals don't carry data&lt;/strong&gt;. But the example we have is perfect for changing to bits, uh?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Received SIGUSR1 signal # 0
Received SIGUSR2 signal # 1
Received SIGUSR2 signal # 1
Received SIGUSR1 signal # 0
Received SIGUSR2 signal # 1
Received SIGUSR1 signal # 0
Received SIGUSR1 signal # 0
Received SIGUSR1 signal # 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's exactly &lt;code&gt;01101000&lt;/code&gt;, the binary representation of the letter "h". We're simply &lt;strong&gt;encoding&lt;/strong&gt; the letter as a binary representation and sending it via signals&lt;/p&gt;

&lt;p&gt;Again, we're &lt;strong&gt;encoding it as a binary&lt;/strong&gt; and sending it &lt;strong&gt;via signals&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How cool is that&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsuge051okg1a7lhquohk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsuge051okg1a7lhquohk.png" alt=" " width="800" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Decoding the binary data
&lt;/h3&gt;

&lt;p&gt;On the other side, the receiver should be capable of decoding the message and converting it back to the letter "h":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sender &lt;em&gt;encodes&lt;/em&gt; the message&lt;/li&gt;
&lt;li&gt;receiver &lt;em&gt;decodes&lt;/em&gt; the message&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, how do we decode &lt;code&gt;01101000&lt;/code&gt; (the letter "h" in ASCII)? Let's break it down into a few steps:&lt;/p&gt;

&lt;p&gt;1) First, we need to see the 8 bits as individual digits in their respective positions&lt;br&gt;
2) The rightmost bit is at position 0, whereas the leftmost bit is at position 7. This is how we define the most significant bit (&lt;strong&gt;MSB&lt;/strong&gt;, the leftmost) and the least significant bit (&lt;strong&gt;LSB&lt;/strong&gt;, the rightmost)&lt;br&gt;
3) For this example, we perform a &lt;strong&gt;left shift&lt;/strong&gt; operation on each bit and then sum all the values, in this case from MSB to LSB (the order doesn't matter much for now): &lt;code&gt;(0 &amp;lt;&amp;lt; 7) + (1 &amp;lt;&amp;lt; 6) + (1 &amp;lt;&amp;lt; 5) + (0 &amp;lt;&amp;lt; 4) + ... + (0 &amp;lt;&amp;lt; 0)&lt;/code&gt;:&lt;br&gt;
&lt;em&gt;left shift on _zeros&lt;/em&gt; will always produce a &lt;em&gt;zero&lt;/em&gt;_&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;0 &amp;lt;&amp;lt; 7&lt;/code&gt; = &lt;code&gt;(2 ** 7) * 0&lt;/code&gt; = &lt;code&gt;128 * 0&lt;/code&gt; = 0 &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;1 &amp;lt;&amp;lt; 6&lt;/code&gt; = &lt;code&gt;(2 ** 6) * 1&lt;/code&gt; = &lt;code&gt;64 * 1&lt;/code&gt; = 64&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Similarly to the remaining bits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;1 &amp;lt;&amp;lt; 5&lt;/code&gt; = 32&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;0 &amp;lt;&amp;lt; 4&lt;/code&gt; = 0&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;1 &amp;lt;&amp;lt; 3&lt;/code&gt; = 8&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;0 &amp;lt;&amp;lt; 2&lt;/code&gt; = 0&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;0 &amp;lt;&amp;lt; 1&lt;/code&gt; = 0&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;0 &amp;lt;&amp;lt; 0&lt;/code&gt; = 0&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, our sum becomes, from MSB to LSB:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MSB                          LSB
0   1    1    0   1   0   0   0
0 + 64 + 32 + 0 + 8 + 0 + 0 + 0 = 104
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;104 is exactly the &lt;strong&gt;decimal representation&lt;/strong&gt; of the letter "h" in ASCII. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;How wonderful is that?&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Sending the letter "h"
&lt;/h3&gt;

&lt;p&gt;Now let's convert these operations to Ruby code. We'll write a simple program &lt;code&gt;receiver.rb&lt;/code&gt; that receives signals in order from LSB to MSB (positions 0 to 7) and then converts them back to ASCII characters, printing to &lt;code&gt;STDOUT&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Basically, we'll &lt;strong&gt;accumulate&lt;/strong&gt; bits and whenever we form a complete byte, we'll decode it to its ASCII representation. The very basic implementation of our &lt;code&gt;accumulate_bit(bit)&lt;/code&gt; method would look like as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="vi"&gt;@position&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;# start with the LSB&lt;/span&gt;
&lt;span class="vi"&gt;@accumulator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;accumulate_bit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;# The left shift operator (&amp;lt;&amp;lt;) is used to &lt;/span&gt;
  &lt;span class="c1"&gt;# shift the bits of the number to the left.&lt;/span&gt;
  &lt;span class="c1"&gt;#&lt;/span&gt;
  &lt;span class="c1"&gt;# This is equivalent of: (2 ** @position) * bit&lt;/span&gt;
  &lt;span class="vi"&gt;@accumulator&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bit&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="vi"&gt;@position&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="vi"&gt;@accumulator&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@position&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="c1"&gt;# stop accumulating after 8 bits (byte)&lt;/span&gt;

  &lt;span class="vi"&gt;@position&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="c1"&gt;# move to the next bit position: 0 becomes 1, 1 becomes 2, etc.&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Letter "h" in binary is 01101000&lt;/span&gt;
&lt;span class="c1"&gt;# But we'll send from the LSB to the MSB&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# 0110 1000 (MSB -&amp;gt; LSB) becomes 0001 0110 (LSB -&amp;gt; MSB)&lt;/span&gt;
&lt;span class="c1"&gt;# The order doesn't matter that much, it'll depend on &lt;/span&gt;
&lt;span class="c1"&gt;# the receiver's implementation.&lt;/span&gt;
&lt;span class="n"&gt;accumulate_bit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;accumulate_bit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;accumulate_bit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;accumulate_bit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;accumulate_bit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;accumulate_bit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;accumulate_bit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;accumulate_bit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="vi"&gt;@accumulator&lt;/span&gt; &lt;span class="c1"&gt;# should print 104, which is the ASCII code for "h"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Pay attention to this code. It's very important and builds the foundation for the next steps. If you didn't get it, go back and read it again. Try it yourself in the terminal or using your preferred programming language.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now, how to convert the decimal &lt;code&gt;104&lt;/code&gt; to the ASCII character representation? Luckily, Ruby provides a method called &lt;code&gt;chr&lt;/code&gt; which does the job:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;irb&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="mi"&gt;104&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chr&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"h"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We could do the same job for the rest of the word "hello", for instance. According to the &lt;a href="https://www.ascii-code.com/" rel="noopener noreferrer"&gt;ASCII table&lt;/a&gt;, it should be the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;e&lt;/code&gt; in decimal is &lt;code&gt;101&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;l&lt;/code&gt; in decimal is &lt;code&gt;108&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;o&lt;/code&gt; in decimal is &lt;code&gt;111&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's check if Ruby knows that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="mi"&gt;104&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chr&lt;/span&gt;    &lt;span class="c1"&gt;# "h"&lt;/span&gt;
&lt;span class="mi"&gt;101&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chr&lt;/span&gt;    &lt;span class="c1"&gt;# "e"&lt;/span&gt;
&lt;span class="mi"&gt;108&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chr&lt;/span&gt;    &lt;span class="c1"&gt;# "l"&lt;/span&gt;
&lt;span class="mi"&gt;111&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chr&lt;/span&gt;    &lt;span class="c1"&gt;# "o"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can even "decode" the word to the decimal representation in ASCII:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;irb&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bytes&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;104&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;101&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;108&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;108&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;111&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, time to finish our receiver implementation to properly print the letter "h":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="vi"&gt;@position&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;# start with the LSB&lt;/span&gt;
&lt;span class="vi"&gt;@accumulator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="nb"&gt;trap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'SIGUSR1'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;decode_signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nb"&gt;trap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'SIGUSR2'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;decode_signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;decode_signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;accumulate_bit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="vi"&gt;@position&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="c1"&gt;# if not yet accumulated a byte, keep accumulating&lt;/span&gt;

  &lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;"Received byte: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@accumulator&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; (&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@accumulator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chr&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

  &lt;span class="vi"&gt;@accumulator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;# reset the accumulator&lt;/span&gt;
  &lt;span class="vi"&gt;@position&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;# reset position for the next byte&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;accumulate_bit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;# The left shift operator (&amp;lt;&amp;lt;) is used to &lt;/span&gt;
  &lt;span class="c1"&gt;# shift the bits of the number to the left.&lt;/span&gt;
  &lt;span class="c1"&gt;#&lt;/span&gt;
  &lt;span class="c1"&gt;# This is equivalent of: (2 ** @position) * bit&lt;/span&gt;
  &lt;span class="vi"&gt;@accumulator&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bit&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="vi"&gt;@position&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="vi"&gt;@position&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="c1"&gt;# move to the next bit position: 0 becomes 1, 1 becomes 2, etc.&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Process ID: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pid&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;sleep&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Read that code and its comments. It's very important. Do not continue reading until you really get what's happening here.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Whenever we get &lt;code&gt;SIGUSR1&lt;/code&gt;, we accumulate the bit &lt;code&gt;0&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;When getting &lt;code&gt;SIGUSR2&lt;/code&gt;, accumulate then the bit &lt;code&gt;1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;When accumulator reaches  the position&lt;code&gt;8&lt;/code&gt;, it means we have a byte. At this moment we should print the ASCII representation using the &lt;code&gt;.chr&lt;/code&gt; we seen earlier. Then, reset bit position and accumulator&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's see our receiver in action! Start the receiver in one terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ruby receiver.rb
Process ID: 58219
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great! Now the receiver is listening for signals. In another terminal, let's manually send signals&lt;br&gt;
  to form the letter "h" (which is &lt;code&gt;01101000&lt;/code&gt; in binary, remember?):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  # Sending from LSB to MSB: 0, 0, 0, 1, 0, 1, 1, 0
  $ kill -SIGUSR1 58219  # 0
  $ kill -SIGUSR1 58219  # 0
  $ kill -SIGUSR1 58219  # 0
  $ kill -SIGUSR2 58219  # 1
  $ kill -SIGUSR1 58219  # 0
  $ kill -SIGUSR2 58219  # 1
  $ kill -SIGUSR2 58219  # 1
  $ kill -SIGUSR1 58219  # 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And in the receiver terminal, we should see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Received byte: 104 (h)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;How amazing is that?&lt;/em&gt; We just sent the letter "h" using only two UNIX signals!&lt;/p&gt;

&lt;p&gt;But wait. Manually sending 8 signals for each character? That's tedious and error-prone. What if we wanted to send the word "hello"? That's 5 characters × 8 bits = 40 signals to send manually. No way.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;We need a sender.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Building the sender
&lt;/h3&gt;

&lt;p&gt;The sender's job is the opposite of the receiver: it should encode a message (string) into bits and send them as signals to the receiver process.&lt;/p&gt;

&lt;p&gt;Let's think about what we need:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Take a message as input (like "hello")&lt;/li&gt;
&lt;li&gt;Convert each character to its byte representation&lt;/li&gt;
&lt;li&gt;Extract the 8 bits from each byte&lt;/li&gt;
&lt;li&gt;Send &lt;code&gt;SIGUSR1&lt;/code&gt; for bit 0, &lt;code&gt;SIGUSR2&lt;/code&gt; for bit 1&lt;/li&gt;
&lt;li&gt;Repeat for all characters&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The tricky part here is the step 3: &lt;strong&gt;how do we extract individual bits from a byte?&lt;/strong&gt; To extract the bit at position &lt;code&gt;i&lt;/code&gt;, we can use the following formula:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bit = (byte &amp;gt;&amp;gt; i) &amp;amp; 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let me break this down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;byte &amp;gt;&amp;gt; i&lt;/code&gt; performs a &lt;em&gt;right shift&lt;/em&gt; by &lt;code&gt;i&lt;/code&gt; positions&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;amp; 1&lt;/code&gt; is a bitwise &lt;code&gt;AND&lt;/code&gt; operation that extracts only the &lt;em&gt;rightmost&lt;/em&gt; bit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the letter "h" (&lt;code&gt;01101000&lt;/code&gt; in binary, &lt;code&gt;104&lt;/code&gt; in decimal):&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Position 0 (LSB):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;(104 &amp;gt;&amp;gt; 0)&lt;/code&gt; = &lt;code&gt;104 / (2 ** 0)&lt;/code&gt; = &lt;code&gt;104 / 1&lt;/code&gt; = 104&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;01101000&lt;/code&gt; &amp;gt;&amp;gt; 0 = &lt;code&gt;01101000&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;01101000&lt;/code&gt; &amp;amp; &lt;code&gt;00000001&lt;/code&gt; = 0 (&lt;em&gt;one&lt;/em&gt; AND &lt;em&gt;zero&lt;/em&gt; is &lt;em&gt;zero&lt;/em&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Position 1:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;(104 &amp;gt;&amp;gt; 1)&lt;/code&gt; = &lt;code&gt;104 / (2 ** 1)&lt;/code&gt; = &lt;code&gt;104 / 2&lt;/code&gt; = 52&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;01101000&lt;/code&gt; &amp;gt;&amp;gt; 1 = &lt;code&gt;00110100&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;00110100&lt;/code&gt; &amp;amp; &lt;code&gt;00000001&lt;/code&gt; = 0&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Position 2:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;(104 &amp;gt;&amp;gt; 2)&lt;/code&gt; = &lt;code&gt;104 / (2 ** 2)&lt;/code&gt; = &lt;code&gt;104 / 4&lt;/code&gt; = 26&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;01101000&lt;/code&gt; &amp;gt;&amp;gt; 2 = &lt;code&gt;00011010&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;00011010&lt;/code&gt; &amp;amp; &lt;code&gt;00000001&lt;/code&gt; = 0&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Position 3:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;(104 &amp;gt;&amp;gt; 3)&lt;/code&gt; = &lt;code&gt;104 / (2 ** 3)&lt;/code&gt; = &lt;code&gt;104 / 8&lt;/code&gt; = 13&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;01101000&lt;/code&gt; &amp;gt;&amp;gt; 3 = &lt;code&gt;00001101&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;00001101&lt;/code&gt; &amp;amp; &lt;code&gt;00000001&lt;/code&gt; = 1 (&lt;em&gt;one&lt;/em&gt; AND &lt;em&gt;one&lt;/em&gt; equals &lt;em&gt;one&lt;/em&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And so on for positions 4, 5, 6, and 7. This gives us: &lt;code&gt;0, 0, 0, 1, 0, 1, 1, 0&lt;/code&gt; — exactly the bits we need from LSB to MSB!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;(104 &amp;gt;&amp;gt; 0) &amp;amp; 1&lt;/code&gt; = &lt;code&gt;104 &amp;amp; 1&lt;/code&gt; = 0&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;(104 &amp;gt;&amp;gt; 1) &amp;amp; 1&lt;/code&gt; = &lt;code&gt;52 &amp;amp; 1&lt;/code&gt; = 0&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;(104 &amp;gt;&amp;gt; 2) &amp;amp; 1&lt;/code&gt; = &lt;code&gt;26 &amp;amp; 1&lt;/code&gt; = 0&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;(104 &amp;gt;&amp;gt; 3) &amp;amp; 1&lt;/code&gt; = &lt;code&gt;13 &amp;amp; 1&lt;/code&gt; = 1&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;(104 &amp;gt;&amp;gt; 4) &amp;amp; 1&lt;/code&gt; = &lt;code&gt;6 &amp;amp; 1&lt;/code&gt; = 0&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;(104 &amp;gt;&amp;gt; 5) &amp;amp; 1&lt;/code&gt; = &lt;code&gt;3 &amp;amp; 1&lt;/code&gt; = 1&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;(104 &amp;gt;&amp;gt; 6) &amp;amp; 1&lt;/code&gt; = &lt;code&gt;1 &amp;amp; 1&lt;/code&gt; = 1&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;(104 &amp;gt;&amp;gt; 7) &amp;amp; 1&lt;/code&gt; = &lt;code&gt;0 &amp;amp; 1&lt;/code&gt; = 0&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Pay close attention to this technique. It's a fundamental operation in low-level programming.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So now time to build the &lt;code&gt;sender.rb&lt;/code&gt; which is pretty simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;receiver_pid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ARGV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;to_i&lt;/span&gt;
&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ARGV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;encode_byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;times&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="c1"&gt;# Extract each bit from the byte, starting from the LSB&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;encode_byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;bit&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;signal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bit&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s1"&gt;'SIGUSR1'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'SIGUSR2'&lt;/span&gt;
    &lt;span class="no"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;kill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;receiver_pid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="mf"&gt;0.001&lt;/span&gt; &lt;span class="c1"&gt;# Delay to allow the receiver to process the signal&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For each byte (8-bit structure) we extract the bit performing the &lt;em&gt;right shift&lt;/em&gt; + &lt;em&gt;AND&lt;/em&gt; oprerations. The result is the extracted bit.&lt;/p&gt;

&lt;p&gt;In the receiver window:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ruby receiver.rb
Process ID: 68968
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And in the sender window:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ruby sender.rb 68968 h
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The receiver will print:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ruby receiver.rb
Process ID: 68968
Received byte: 104 &lt;span class="o"&gt;(&lt;/span&gt;h&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Processes sending messages with only two signals!&lt;/em&gt; How wonderful is that?&lt;/p&gt;

&lt;h3&gt;
  
  
  Sending the "hello" message
&lt;/h3&gt;

&lt;p&gt;Now, sending the hello message is super easy. The sender is already able to send not only a letter but any message using signals:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ruby sender.rb 68968 hello

&lt;span class="c"&gt;# And the receiver:&lt;/span&gt;
Received byte: 104 &lt;span class="o"&gt;(&lt;/span&gt;h&lt;span class="o"&gt;)&lt;/span&gt;
Received byte: 101 &lt;span class="o"&gt;(&lt;/span&gt;e&lt;span class="o"&gt;)&lt;/span&gt;
Received byte: 108 &lt;span class="o"&gt;(&lt;/span&gt;l&lt;span class="o"&gt;)&lt;/span&gt;
Received byte: 108 &lt;span class="o"&gt;(&lt;/span&gt;l&lt;span class="o"&gt;)&lt;/span&gt;
Received byte: 111 &lt;span class="o"&gt;(&lt;/span&gt;o&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just change the &lt;code&gt;receiver&lt;/code&gt; implementation a little bit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;decode_signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;accumulate_bit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="vi"&gt;@position&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="c1"&gt;# if not yet accumulated a byte, keep accumulating&lt;/span&gt;

  &lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="vi"&gt;@accumulator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chr&lt;/span&gt; &lt;span class="c1"&gt;# print the byte as a character&lt;/span&gt;

  &lt;span class="vi"&gt;@accumulator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;# reset the accumulator&lt;/span&gt;
  &lt;span class="vi"&gt;@position&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;# reset position for the next byte&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ruby sender.rb 96875 Hello

&lt;span class="c"&gt;# In the receiver's terminal&lt;/span&gt;
Process ID: 96875
Hello
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, if we send the message again, the receiver will print everything in the same line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;ruby&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt; &lt;span class="mi"&gt;96875&lt;/span&gt; &lt;span class="no"&gt;Hello&lt;/span&gt;
&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;ruby&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt; &lt;span class="mi"&gt;96875&lt;/span&gt; &lt;span class="no"&gt;Hello&lt;/span&gt;

&lt;span class="c1"&gt;# In the receiver's terminal&lt;/span&gt;
&lt;span class="no"&gt;Process&lt;/span&gt; &lt;span class="no"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;96875&lt;/span&gt;
&lt;span class="no"&gt;HelloHello&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's obvious: the receiver doesn't know where the sender finished the message, so it's impossible to know where we should stop one message and print the next one on a new line with &lt;code&gt;\n&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We should then determine how the sender indicates the end of the message. How about being it all &lt;em&gt;zeroes&lt;/em&gt; (&lt;code&gt;0000 0000&lt;/code&gt;)?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We send the message: first 5 bytes representing the "hello" message&lt;/li&gt;
&lt;li&gt;Then we send a "NULL terminator", just one byte &lt;em&gt;0&lt;/em&gt; (&lt;code&gt;0000 0000&lt;/code&gt;)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0110 1000 # h
0110 0101 # e
0110 1000 # l
0110 1000 # l
0110 1111 # o
0000 0000 # NULL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hence, when the &lt;em&gt;receiver&lt;/em&gt; gets a NULL terminator, it will print a line feed &lt;code&gt;\n&lt;/code&gt;. Let's change the &lt;code&gt;sender.rb&lt;/code&gt; first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;receiver_pid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ARGV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;to_i&lt;/span&gt;
&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ARGV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;encode_byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;times&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="c1"&gt;# Extract each bit from the byte, starting from the LSB&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;encode_byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;bit&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;signal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bit&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s1"&gt;'SIGUSR1'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'SIGUSR2'&lt;/span&gt;
    &lt;span class="no"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;kill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;receiver_pid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="mf"&gt;0.001&lt;/span&gt; &lt;span class="c1"&gt;# Delay to allow the receiver to process the signal&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Send NULL terminator (0000 0000)&lt;/span&gt;
&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;times&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="no"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;kill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'SIGUSR1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;receiver_pid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="mf"&gt;0.001&lt;/span&gt; &lt;span class="c1"&gt;# Delay to allow the receiver to process the signal&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Message sent to receiver (PID: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;receiver_pid&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, the &lt;code&gt;receiver.rb&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="vi"&gt;@position&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;# start with the LSB&lt;/span&gt;
&lt;span class="vi"&gt;@accumulator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="nb"&gt;trap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'SIGUSR1'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;decode_signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nb"&gt;trap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'SIGUSR2'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;decode_signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;decode_signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;accumulate_bit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="vi"&gt;@position&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="c1"&gt;# if not yet accumulated a byte, keep accumulating&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@accumulator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zero?&lt;/span&gt; &lt;span class="c1"&gt;# NULL terminator received&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="vi"&gt;@accumulator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chr&lt;/span&gt; &lt;span class="c1"&gt;# print the byte as a character&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="vi"&gt;@accumulator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;# reset the accumulator&lt;/span&gt;
  &lt;span class="vi"&gt;@position&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;# reset position for the next byte&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;accumulate_bit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;# The left shift operator (&amp;lt;&amp;lt;) is used to &lt;/span&gt;
  &lt;span class="c1"&gt;# shift the bits of the number to the left.&lt;/span&gt;
  &lt;span class="c1"&gt;#&lt;/span&gt;
  &lt;span class="c1"&gt;# This is equivalent of: (2 ** @position) * bit&lt;/span&gt;
  &lt;span class="vi"&gt;@accumulator&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bit&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="vi"&gt;@position&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="vi"&gt;@position&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="c1"&gt;# move to the next bit position: 0 becomes 1, 1 becomes 2, etc.&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Process ID: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pid&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;sleep&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ruby sender.rb 96875 Hello, World!
$ ruby sender.rb 96875 You're welcome
$ ruby sender.rb 96875 How are you?

# Receiver
Process ID: 97176
Hello, World!
You're welcome
How are you?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;OMG Leandro! That's amazing!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Amazing, right?&lt;/em&gt; We just built an entire communication system between two processes using one of the most primitive methods available: &lt;strong&gt;UNIX signals.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The sky's the limit now! Why not build a &lt;em&gt;full-fledged message broker&lt;/em&gt; using this crazy technique?&lt;/p&gt;

&lt;h2&gt;
  
  
  A modest message broker using UNIX signals
&lt;/h2&gt;

&lt;p&gt;We'll break down the development into three components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Broker&lt;/strong&gt;: the intermediary that routes messages&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consumer&lt;/strong&gt;: processes that receive messages&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Producer&lt;/strong&gt;: processes that send messages&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Let's start with the Broker. It should register itself with the producer, then trap incoming signals, decode them, and enqueue the messages for delivery to consumers via outgoing signals:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;

&lt;span class="nb"&gt;require_relative&lt;/span&gt; &lt;span class="s1"&gt;'signal_codec'&lt;/span&gt;
&lt;span class="nb"&gt;require_relative&lt;/span&gt; &lt;span class="s1"&gt;'consumer'&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Broker&lt;/span&gt; 
  &lt;span class="no"&gt;PID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'broker.pid'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;
    &lt;span class="vi"&gt;@codec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;SignalCodec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
    &lt;span class="vi"&gt;@queue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
    &lt;span class="vi"&gt;@consumer_index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;start&lt;/span&gt; 
    &lt;span class="n"&gt;register_broker&lt;/span&gt;

    &lt;span class="nb"&gt;trap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'SIGUSR1'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;process_bit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nb"&gt;trap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'SIGUSR2'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;process_bit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Broker PID: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pid&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Waiting for messages..."&lt;/span&gt;

    &lt;span class="n"&gt;distribute_messages&lt;/span&gt;

    &lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="c1"&gt;# Keep alive&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt; 

  &lt;span class="kp"&gt;private&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_bit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@codec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;accumulate_bit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="vi"&gt;@queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;empty?&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;register_broker&lt;/span&gt; 
    &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;PID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;at_exit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;PID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exist?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;PID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;distribute_messages&lt;/span&gt;
    &lt;span class="no"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="kp"&gt;loop&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;

        &lt;span class="k"&gt;next&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;empty?&lt;/span&gt;

        &lt;span class="n"&gt;consumers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exist?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Consumer&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;FILE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readlines&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Consumer&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;FILE&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:to_i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="k"&gt;next&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;consumers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;empty?&lt;/span&gt;

        &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="k"&gt;next&lt;/span&gt;

        &lt;span class="n"&gt;consumer_pid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;consumers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="vi"&gt;@consumer_index&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;consumers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="vi"&gt;@consumer_index&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

        &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"[SEND] &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; → Consumer &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;consumer_pid&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

        &lt;span class="vi"&gt;@codec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;consumer_pid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="kp"&gt;__FILE__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="vg"&gt;$0&lt;/span&gt; 
  &lt;span class="n"&gt;broker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Broker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
  &lt;span class="n"&gt;broker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The broker registers itself&lt;/li&gt;
&lt;li&gt;Traps incoming signals &lt;code&gt;USR1&lt;/code&gt; (bit 0) and &lt;code&gt;USR2&lt;/code&gt; (bit 1)&lt;/li&gt;
&lt;li&gt;Enqueues the messages&lt;/li&gt;
&lt;li&gt;Send messages to consumers using outgoing signals (&lt;code&gt;USR1&lt;/code&gt; and &lt;code&gt;USR2&lt;/code&gt; too)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Note that we're using a module called &lt;code&gt;SignalCodec&lt;/code&gt; which will be explained soon. Basically this module contains all core components to encode/decode signals and perform bitwise operations.&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Now the &lt;code&gt;Consumer&lt;/code&gt; implementation:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;

&lt;span class="nb"&gt;require_relative&lt;/span&gt; &lt;span class="s1"&gt;'signal_codec'&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Consumer&lt;/span&gt;
  &lt;span class="no"&gt;FILE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'consumers.txt'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;
    &lt;span class="vi"&gt;@codec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;SignalCodec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;start&lt;/span&gt;
    &lt;span class="n"&gt;register_consumer&lt;/span&gt;

    &lt;span class="nb"&gt;trap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'SIGUSR1'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;process_bit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nb"&gt;trap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'SIGUSR2'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;process_bit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Consumer PID: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pid&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Waiting for messages..."&lt;/span&gt;

    &lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="c1"&gt;# Keep alive&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="kp"&gt;private&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_bit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@codec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;accumulate_bit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"[RECEIVE] &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;register_consumer&lt;/span&gt;
    &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;FILE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;puts&lt;/span&gt; &lt;span class="no"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pid&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nb"&gt;at_exit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;deregister_consumer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;deregister_consumer&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exist?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;FILE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;consumers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readlines&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;FILE&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:strip&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;reject&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_i&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pid&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;FILE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;consumers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="kp"&gt;__FILE__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="vg"&gt;$0&lt;/span&gt;
  &lt;span class="n"&gt;consumer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Consumer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
  &lt;span class="n"&gt;consumer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The consumer starts and registers itself with the broker&lt;/li&gt;
&lt;li&gt;Consumer then traps incoming signals (bit 0 and bit 1)&lt;/li&gt;
&lt;li&gt;Decodes and prints messages&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Last but not least, the &lt;code&gt;Producer&lt;/code&gt; implementation, which is pretty straightforward:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;

&lt;span class="nb"&gt;require_relative&lt;/span&gt; &lt;span class="s1"&gt;'signal_codec'&lt;/span&gt;
&lt;span class="nb"&gt;require_relative&lt;/span&gt; &lt;span class="s1"&gt;'broker'&lt;/span&gt;

&lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exist?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Broker&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;PID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;abort&lt;/span&gt; &lt;span class="s2"&gt;"Error: Broker not running (&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;Broker&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;PID&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; not found)"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;broker_pid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Broker&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;PID&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_i&lt;/span&gt;
&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ARGV&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;empty?&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Usage: ruby producer.rb &amp;lt;message&amp;gt;"&lt;/span&gt;
  &lt;span class="nb"&gt;exit&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;codec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;SignalCodec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Sending: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;codec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;broker_pid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Message sent to broker (PID: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;broker_pid&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Producer receives a ASCII message from the &lt;em&gt;STDIN&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Encode and sends the message to the broker via outgoing signals&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So far, this architecture should look familiar. Many broker implementations follow these basic foundations.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Of course, production-ready implementations are far more robust than this one. Here, we're just poking around with hacking and experimentation&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The coolest part is the &lt;code&gt;SignalCodec&lt;/code&gt; though:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SignalCodec&lt;/span&gt; 
  &lt;span class="no"&gt;SIGNAL_DELAY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.001&lt;/span&gt; &lt;span class="c1"&gt;# Delay between signals to allow processing&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;
    &lt;span class="vi"&gt;@accumulator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="vi"&gt;@position&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="vi"&gt;@buffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;accumulate_bit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@accumulator&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bit&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="vi"&gt;@position&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@position&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@position&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="c1"&gt;# Byte is complete&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@accumulator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zero?&lt;/span&gt; &lt;span class="c1"&gt;# Message complete - NULL terminator&lt;/span&gt;
        &lt;span class="n"&gt;decoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"C*"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;force_encoding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'UTF-8'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;decoded&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;block_given?&lt;/span&gt;
        &lt;span class="vi"&gt;@buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt; 
        &lt;span class="vi"&gt;@buffer&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="vi"&gt;@accumulator&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="vi"&gt;@position&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
      &lt;span class="vi"&gt;@accumulator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;send_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_byte&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;times&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="n"&gt;bit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="n"&gt;signal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bit&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s1"&gt;'SIGUSR1'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'SIGUSR2'&lt;/span&gt;
        &lt;span class="no"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;kill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="no"&gt;SIGNAL_DELAY&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# Send NULL terminator (0000 0000)&lt;/span&gt;
    &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;times&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="no"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;kill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'SIGUSR1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="no"&gt;SIGNAL_DELAY&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you've been following along, this shouldn't be hard to understand, but I'll break down how this beautiful piece of code works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The codec is initialized with the bit position at zero, as well as the accumulator&lt;/li&gt;
&lt;li&gt;A buffer is also initialized to store accumulated bits until a complete byte is formed&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;accumulate_bit&lt;/code&gt; method should be familiar from our earlier implementation, but it now accepts a closure (block) that lets the caller decide what to do with each decoded byte&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;send_message&lt;/code&gt; encodes a message into bits and sends them via UNIX signals&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything in action:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1v0k4upry5ljuibqp6f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1v0k4upry5ljuibqp6f.png" alt=" " width="800" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How cool, amazing, wonderful, impressive, astonishing is that?&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Yes, we built a message broker using nothing but &lt;strong&gt;UNIX signals&lt;/strong&gt; and a bit of Ruby magic. Sure, &lt;strong&gt;it's not production-ready&lt;/strong&gt;, and you definitely shouldn't use this in your next startup (please don't), but that was never the point.&lt;/p&gt;

&lt;p&gt;The real takeaway here isn't the broker itself: it's understanding how the fundamentals work. We explored binary operations, UNIX signals, and IPC in a hands-on way that most people never bother with.&lt;/p&gt;

&lt;p&gt;We took something "useless" and made it work, just for fun. So next time someone asks you about message brokers, you can casually mention that you once built (or saw) one using just two signals. And if they look at you weird, well, that's their problem. Now go build something equally useless and amazing. The world needs more hackers who experiment just for the fun of it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Happy hacking!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>kafka</category>
      <category>unix</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Leandro Proença</dc:creator>
      <pubDate>Sun, 12 Jan 2025 21:42:59 +0000</pubDate>
      <link>https://dev.to/leandronsp/-22mo</link>
      <guid>https://dev.to/leandronsp/-22mo</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/jessilyneh" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F170161%2F065bcc7a-446e-4433-ad63-2fa5fa85bba2.jpg" alt="jessilyneh"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/jessilyneh/o-que-realmente-agregou-profissionalmente-quando-eu-era-junior-4ael" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;O que realmente agregou profissionalmente quando eu era Junior&lt;/h2&gt;
      &lt;h3&gt;Jessilyneh ・ Jan 10&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#career&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#beginners&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>career</category>
      <category>beginners</category>
      <category>productivity</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Leandro Proença</dc:creator>
      <pubDate>Thu, 02 Jan 2025 16:15:20 +0000</pubDate>
      <link>https://dev.to/leandronsp/-255d</link>
      <guid>https://dev.to/leandronsp/-255d</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/leandronsp" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F29160%2F7682c138-1242-4179-add4-9a810e9afafd.jpeg" alt="leandronsp"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/leandronsp/um-resumo-do-meu-2024-1lf4" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Um resumo do meu 2024&lt;/h2&gt;
      &lt;h3&gt;Leandro Proença ・ Dec 31 '24&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#braziliandevs&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>braziliandevs</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>Um resumo do meu 2024</title>
      <dc:creator>Leandro Proença</dc:creator>
      <pubDate>Tue, 31 Dec 2024 20:27:13 +0000</pubDate>
      <link>https://dev.to/leandronsp/um-resumo-do-meu-2024-1lf4</link>
      <guid>https://dev.to/leandronsp/um-resumo-do-meu-2024-1lf4</guid>
      <description>&lt;p&gt;31 de Dezembro de 2024.&lt;br&gt;
Sentado no sofá e assistindo Frozen, tive a ideia de escrever sobre minha retrospectiva deste ano. Nunca fiz isso antes, então bora lá, porque acho que foi muita coisa.&lt;/p&gt;




&lt;h2&gt;
  
  
  Mas antes, um aftermath de 2023
&lt;/h2&gt;

&lt;p&gt;2023 foi um ano bastante agitado pra mim. Passei por uma &lt;a href="https://pt.wikipedia.org/wiki/Tiroidectomia" rel="noopener noreferrer"&gt;tireoidectomia&lt;/a&gt; (mas estou bem, obrigado) e também foi o ano em que resolvi fazer "learn in public" e deixar tudo gravado no &lt;a href="https://www.youtube.com/@leandronsp" rel="noopener noreferrer"&gt;meu canal do Youtube&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Iniciei cobrindo a rinha de compiladores, onde submeti &lt;a href="https://github.com/leandronsp/patropi" rel="noopener noreferrer"&gt;uma versão em Ruby&lt;/a&gt;, e depois fui trazendo &lt;a href="https://www.youtube.com/watch?v=6VSgMbFNUuQ" rel="noopener noreferrer"&gt;conteúdo para iniciantes&lt;/a&gt; em Rust. &lt;br&gt;
Teve também transmissão ao vivo criando uma &lt;a href="https://www.youtube.com/watch?v=4jY_Vwnm-es" rel="noopener noreferrer"&gt;Rede Neural Artificial em Ruby&lt;/a&gt;, então vi que eu realmente estava gostando de compartilhar minha jornada &lt;em&gt;coding in public&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Na parte de artigos, &lt;a href="https://dev.to/leandronsp"&gt;escrevi muita coisa&lt;/a&gt; em 2023:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Introdução ao &lt;a href="https://dev.to/leandronsp/tekton-ci-part-i-a-gentle-introduction-ilj"&gt;Tekton CI/CD&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/leandronsp/kubernetes-101-part-i-the-fundamentals-23a1"&gt;Kubernetes 101&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Um guia completo cobrindo &lt;a href="https://dev.to/leandronsp/git-fundamentals-a-complete-guide-do7"&gt;os fundamentos de Git&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Criando &lt;a href="https://dev.to/leandronsp/ai-ruby-an-introduction-to-neural-networks-23f3"&gt;redes neurais em Ruby&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Teve até artigo sobre &lt;a href="https://dev.to/leandronsp/vencendo-os-numeros-de-ponto-flutuante-um-guia-de-sobrevivencia-4n7n"&gt;ponto flutuante&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/leandronsp/entendendo-fundamentos-de-recursao-2ap4"&gt;Fundamentos de recursão&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/leandronsp/compiladores-trampolim-deque-e-thread-pool-dd1"&gt;Resumo da rinha de compiladores&lt;/a&gt; e trampolim&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/leandronsp/understanding-the-basics-of-smart-pointers-in-rust-3dff"&gt;Mais Rust&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;E o famoso &lt;a href="https://web101.leandronsp.com/" rel="noopener noreferrer"&gt;Guia Web 101&lt;/a&gt; também.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Mentira, esse guia web foi em 2021, mas eu quis colocar ele aqui só pra fazer propaganda mesmo&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  As metas para 2024
&lt;/h2&gt;

&lt;p&gt;No fim de 2023 estabeleci algumas metas pra 2024 nessa parte de criação de conteúdo. Mas não foram metas muito arrojadas pois eu queria dar uma desaquecida do que foi o agitado 2023.&lt;/p&gt;

&lt;p&gt;Dentre as metas estava continuar explorando Rust; escrever um &lt;strong&gt;guia completo de concorrência&lt;/strong&gt;; criar um interpretador em Ruby; fazer lives com Kubernetes; falar sobre tédio e; Awk.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Sim, Awk&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Podemos confirmar isto em meio a tantos rascunhos que tenho nesta plataforma:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F34ejih5wbhkmueyxz0qk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F34ejih5wbhkmueyxz0qk.png" alt="Image description" width="800" height="865"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  E chegou 2024
&lt;/h2&gt;

&lt;p&gt;Comecei o ano de 2024 focado em me aprofundar em Rust, tanto que em Janeiro até cheguei a criar o &lt;a href="https://github.com/leandronsp/crust" rel="noopener noreferrer"&gt;crust&lt;/a&gt; (outro CRUD, mas desta vez em Rust) e o &lt;a href="https://github.com/leandronsp/aspirina" rel="noopener noreferrer"&gt;aspirina&lt;/a&gt; (outra rede neural, mas desta vez em Rust) durante algumas lives. Queria também iniciar meus estudos em Rust na parte de I/O assíncrono. Era esse o plano.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Era&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Rinha de Backend, 2ª edição
&lt;/h3&gt;

&lt;p&gt;Mas aí veio a rinha de backend do Zan pra tirar meu foco e resolvi fazer lives compartilhando minha solução submetida, que inicialmente seria em Ruby, com o &lt;a href="https://github.com/leandronsp/agostinho" rel="noopener noreferrer"&gt;agostinho&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=VR4mF9TMPws" rel="noopener noreferrer"&gt;Ledo&lt;/a&gt; &lt;a href="https://www.youtube.com/watch?v=5nDfz1dkX2o" rel="noopener noreferrer"&gt;engano&lt;/a&gt;. Acabei por submeter 5 diferentes soluções:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;3 em Ruby: &lt;a href="https://github.com/leandronsp/agostinho" rel="noopener noreferrer"&gt;agostinho&lt;/a&gt;, que usa meus micro frameworks favoritos Adelnor e Chespirito; &lt;a href="https://github.com/leandronsp/tortuga" rel="noopener noreferrer"&gt;tortuga&lt;/a&gt; que não usa framework nem biblioteca alguma, o puro suco de uma linguagem criada no Japão; e &lt;a href="https://github.com/leandronsp/tonico" rel="noopener noreferrer"&gt;tonico&lt;/a&gt;, uma versão sem frameworks que usa I/O assíncrono &lt;em&gt;all the way down&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;1 em Rust: &lt;a href="https://github.com/leandronsp/quokka" rel="noopener noreferrer"&gt;quokka&lt;/a&gt;, criado durante uma live&lt;/li&gt;
&lt;li&gt;e claro, a famosa versão em Bash, &lt;a href="https://github.com/leandronsp/canabrava" rel="noopener noreferrer"&gt;canabrava&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Foram muitas horas em lives, inclusive esta onde eu mostrava como criar uma &lt;a href="https://www.youtube.com/watch?v=lD3gaazwptk" rel="noopener noreferrer"&gt;thread pool e connection pool em Rust&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Nossa Leandro, como você arranja tempo pra fazer lives? Eu não consigo ter tempo pra isso&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Isso é problema seu, e não meu.&lt;/p&gt;

&lt;h3&gt;
  
  
  Um leve sopro do Gleam e o grande tutorial de Assembly
&lt;/h3&gt;

&lt;p&gt;No início do ano notei um pequeno hype em cima do &lt;strong&gt;Gleam&lt;/strong&gt;. Decidi &lt;a href="https://www.youtube.com/watch?v=0XTtAra0l8Q" rel="noopener noreferrer"&gt;explorar em live&lt;/a&gt;. Até que gostei da linguagem, e estava determinado a continuar estudando.&lt;/p&gt;

&lt;p&gt;Mas aí minha amiga e meu amigo, algumas pessoas do trabalho começaram a me provocar. Ficavam colocando &lt;strong&gt;Assembly&lt;/strong&gt; na minha frente. Foi quando numa 6a feira sem pretensão, no Discord, eu e mais alguns colegas fizemos um &lt;a href="https://www.tutorialspoint.com/assembly_programming/index.htm" rel="noopener noreferrer"&gt;tutorial rápido&lt;/a&gt; de Assembly x86. &lt;/p&gt;

&lt;p&gt;Foi quando pensei "ta aí, vou aprender esse negócio e criar um web server multi-threaded simples em Assembly, compartilhando a jornada tanto em artigos quanto em lives".&lt;/p&gt;

&lt;h3&gt;
  
  
  A saga do Assembly x86
&lt;/h3&gt;

&lt;p&gt;Fiz várias lives pela manhã (que eu chamava de lives matinais, duh), mostrando o desenvolvimento do web server e minha saga de aprendizado. Foi incrível, pude ter contato com pessoas como o &lt;a href="https://www.youtube.com/@debxp" rel="noopener noreferrer"&gt;Blau Araújo&lt;/a&gt; que é referência em conteúdo pt-BR em Assembly e outras coisas de baixo nível. &lt;/p&gt;

&lt;p&gt;Tem um vídeo no meu canal, que é a minha "sincera" reação quando o server finalmente funcionou devolvendo a primeira resposta HTTP, &lt;a href="https://www.youtube.com/watch?v=un-7IGJiXeo" rel="noopener noreferrer"&gt;ao vivo em live&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Não obstante, resolvi também &lt;a href="https://www.youtube.com/watch?v=bMGrJU1eRXU" rel="noopener noreferrer"&gt;escrever artigos em live&lt;/a&gt;. Me diga, quem em sã consciência acompanha alguém escrevendo um artigo em live durante umas 4 ou 5 horas?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Não sei quem é mais maluco&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Brincadeiras a parte, e ideia é mesmo compartilhar o processo. É sobre o &lt;em&gt;modus operandi&lt;/em&gt;, a forma como eu quebro o raciocínio em partes na hora de escrever. E também o que me inspira.&lt;/p&gt;

&lt;p&gt;No mundo dos artigos, eu &lt;a href="https://dev.to/leandronsp/construindo-um-web-server-em-assembly-x86-parte-i-introducao-14p5"&gt;comecei em Abril&lt;/a&gt; a saga "Escrevendo um Web server em Assembly x86". Foram um total de 6 artigos, onde no final conseguimos implementar um web server simples, porém multi-threaded em Assembly. Foram 3 meses escrevendo, fazendo lives e &lt;a href="https://github.com/leandronsp/monica" rel="noopener noreferrer"&gt;muitos conceitos abordados&lt;/a&gt;, muita coisa mesmo.&lt;/p&gt;

&lt;p&gt;Aproveitei também para escrever sobre &lt;a href="https://dev.to/leandronsp/arrays-em-assembly-x86-55hb"&gt;Arrays em Assembly x86&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Esta saga foi muito enriquecedora pra mim. Pude aprender e firmar muitos conceitos. Vale muito a pena aprender Assembly e coisas de baixo nível.&lt;/p&gt;

&lt;h3&gt;
  
  
  Enfim o "Guia de Concorrência 101"
&lt;/h3&gt;

&lt;p&gt;Quando finalizei a saga de Assembly, resolvi voltar para uma das coisas que eu tinha como meta para 2024: escrever sobre &lt;strong&gt;concorrência&lt;/strong&gt;. Este é um tema que estudo há mais de 5 anos quase que diariamente, experimentando e validando conceitos.&lt;/p&gt;

&lt;p&gt;Foi então que bem agora, agorinha mesmo (risos) no final de Novembro que comecei a escrever o &lt;a href="https://concorrencia101.leandronsp.com/" rel="noopener noreferrer"&gt;guia de concorrência&lt;/a&gt; (pt-BR). Por enquanto já abordei conceitos de concorrência no sistema operacional e como a linguagem C implementa as principais primitivas de concorrência. Mas o intuito é cobrir com mais linguagens de programação: Ruby, Python, PHP, NodeJS, Go, Rust, Elixir, Java, Kotlin e mais o que vier à cabeça.&lt;/p&gt;

&lt;p&gt;Com uma brincadeira no bluesky, o &lt;a href="https://bsky.app/profile/rdenadai.com.br" rel="noopener noreferrer"&gt;Rodolfo de Nadai&lt;/a&gt; (meu primeiro investidor) deu uma ideia de eu lançar um "buy me a coffee" neste guia. Lancei e gostei da ideia, tanto que no momento são &lt;a href="https://concorrencia101.leandronsp.com/agradecimentos" rel="noopener noreferrer"&gt;23 apoiadores&lt;/a&gt; do projeto. Apesar de que faço de forma genuína sem interesse financeiro, pois defendo muito o conhecimento livre, este apoio da galera tem sido crucial para que eu continuasse, desde o apoio com Pix, revisão ou mesmo compartlihamento do conteúdo.&lt;/p&gt;

&lt;p&gt;Gratidão a todos vocês que fazem isto acontecer ❤&lt;/p&gt;

&lt;h3&gt;
  
  
  Misc
&lt;/h3&gt;

&lt;p&gt;Outras coisas que explorei ao longo deste ano, enquanto ia focando nas coisas de Assembly e concorrência:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/leandronsp/necelu" rel="noopener noreferrer"&gt;leandronsp/necelu&lt;/a&gt;, brincando com Lucene em Java (relembrando &lt;em&gt;the good old days&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/leandronsp/otel-rails" rel="noopener noreferrer"&gt;open telemetry&lt;/a&gt;: OTel é um assunto bem interessante, onde quero me aprofundar em 2025&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/leandronsp/yacs" rel="noopener noreferrer"&gt;leandronsp/yacs&lt;/a&gt;, Yet Another City Search, uma busca textual ultra-rápida em PostgreSQL em mais de 12 milhões de geonames/cidades&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  O que esperar pra 2025
&lt;/h2&gt;

&lt;p&gt;Para 2025, espero mergulhar mais fundo em Rust, explorar OpenTelemetry e, quem sabe, encarar outra linguagem inusitada. &lt;/p&gt;

&lt;p&gt;Afinal, aprender nunca é demais. 🚀&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Feliz 2025 a todes &amp;lt;3&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Arrays em Assembly x86</title>
      <dc:creator>Leandro Proença</dc:creator>
      <pubDate>Sat, 17 Aug 2024 21:49:05 +0000</pubDate>
      <link>https://dev.to/leandronsp/arrays-em-assembly-x86-55hb</link>
      <guid>https://dev.to/leandronsp/arrays-em-assembly-x86-55hb</guid>
      <description>&lt;p&gt;Recentemente escrevi &lt;a href="https://dev.to/leandronsp/series/27062"&gt;uma saga de 6 artigos&lt;/a&gt; sobre Assembly x86, abordando conceitos fundamentais de arquitetura de computadores e programação low-level enquanto ia desenvolvendo um web server minimalista multi-threaded.&lt;/p&gt;

&lt;p&gt;Durante o processo, acabei deixando de lado alguns conceitos importantes para artigos posteriores, pois se fosse abordar durante a saga, iria ficar maior do que já foi. Entretanto são conceitos que podem ser tratados à parte, como no caso das filas implementadas na thread pool.&lt;/p&gt;

&lt;p&gt;E quando falamos de filas, &lt;strong&gt;fica inevitável abordar arrays&lt;/strong&gt; e como estes são organizados na memória do computador.&lt;/p&gt;

&lt;p&gt;Neste artigo, vamos abordar conceitos fundamentais como manipulação de memória, registradores e memória heap ao longo da implementação de arrays.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Vou assumir que você já tem familiaridade com Assembly x86 e a ferramenta GDB. Caso não tenha, recomendo fortemente a leitura da minha saga.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Agenda
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Arrays não existem&lt;/li&gt;
&lt;li&gt;Strings também não existem&lt;/li&gt;
&lt;li&gt;O array mais simples do universo&lt;/li&gt;
&lt;li&gt;
Utilizando um array com dados não inicializados

&lt;ul&gt;
&lt;li&gt;Índice para o resgate&lt;/li&gt;
&lt;li&gt;Atingindo o limite do array&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Heap, heap, hooray!

&lt;ul&gt;
&lt;li&gt;Alocação dinâmica de memória com brk&lt;/li&gt;
&lt;li&gt;Ponteiros, ponteiros everywhere&lt;/li&gt;
&lt;li&gt;Resize com brk&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;O programa final&lt;/li&gt;

&lt;li&gt;Conclusão&lt;/li&gt;

&lt;li&gt;Referências&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  Arrays não existem
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Arrays não existem.&lt;/em&gt; Simples assim. &lt;/p&gt;

&lt;p&gt;Como vimos &lt;a href="https://dev.to/leandronsp/construindo-um-web-server-em-assembly-x86-parte-iv-um-assembly-modesto-oif"&gt;na parte IV&lt;/a&gt; da saga, a memória é organizada de forma contígua, onde as informações são alocadas uma após a outra.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu90q0z4ka96nccs1syef.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu90q0z4ka96nccs1syef.png" alt="memoria é contígua"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Supondo que queremos declarar a seguinte sequência de informações:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

1, 2, 'H', 0


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Eu sei, eu sei, os tipos estão misturados, mas isto não importa para este momento. Todos eles cabem em 1 byte&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Em assembly x86 (vamos chamar de asm no restante do artigo), podemos declarar estas informações da seguinte forma na seção de dados:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;stuff&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="mh"&gt;0x1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x48&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x0&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Lembrando que o caracter 'H' na tabela ASCII representa 0x48 em hexadecimal&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ao utilizarmos o &lt;code&gt;gdb&lt;/code&gt; para fazer debugging, podemos confirmar que esta sequência de hexadecimal no rótulo &lt;code&gt;stuff&lt;/code&gt; está armazenada da seguinte forma:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="c"&gt;# Leitura do primeiro hexabyte em stuff&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x/1xb &lt;span class="o"&gt;(&lt;/span&gt;void&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &amp;amp;stuff
0x402000 &amp;lt;stuff&amp;gt;:       0x01

&lt;span class="c"&gt;# Leitura do segundo hexabyte em stuff&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x/1xb &lt;span class="o"&gt;(&lt;/span&gt;void&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &amp;amp;stuff+1
0x402001:       0x02

&lt;span class="c"&gt;# Leitura do terceiro hexabyte em stuff&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x/1xb &lt;span class="o"&gt;(&lt;/span&gt;void&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &amp;amp;stuff+2
0x402002:       0x48


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Podemos também representar o hexadecimal &lt;code&gt;0x48&lt;/code&gt; em formato de string utilizando &lt;code&gt;x/s&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x/s &lt;span class="o"&gt;(&lt;/span&gt;void&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &amp;amp;stuff+2
0x402002:       &lt;span class="s2"&gt;"H"&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;É tudo hexadecimal!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Com isto, caso queiramos representar a string "Hello", de acordo com a tabela ASCII, poderia ficar assim:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="mh"&gt;0x48&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x65&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x6C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x6C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x6F&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x0&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;No gdb vamos verificar a representação string do rótulo &lt;code&gt;msg&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x/s &amp;amp;msg
0x402000 &amp;lt;msg&amp;gt;: &lt;span class="s2"&gt;"Hello"&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Em asm, é possível declarar a string já com a representação direta da tabela ASCII:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"Hello"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x0&lt;/span&gt;

&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="err"&gt;é&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;mesmo&lt;/span&gt; &lt;span class="nx"&gt;que&lt;/span&gt;
&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="mh"&gt;0x48&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x65&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x6C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x6C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x6F&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x0&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h2&gt;
  
  
  Strings também não existem
&lt;/h2&gt;

&lt;p&gt;Ou seja, é tudo hexadecimal na memória. Um array, assim como uma string, é simplesmente uma sequência contígua de dados &lt;strong&gt;com mesmo tamanho&lt;/strong&gt; na memória.&lt;/p&gt;

&lt;p&gt;A diferença é que a string é um "array especial" que tem dados que representam caracteres da tabela ASCII (note que ambos precisam delimitar um byte "final" para representar o término da string ou array):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdw5cjo8fvoh7rvp8t2l3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdw5cjo8fvoh7rvp8t2l3.png" alt="string e array"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  O array mais simples possível
&lt;/h2&gt;

&lt;p&gt;A seguir temos a implementação de um array bastante simples em asm, pelo que iremos explorar cada passo nas seções subsequentes:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;global&lt;/span&gt; &lt;span class="nx"&gt;_start&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;EXIT_SUCCESS&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;array&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;
&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;al&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;        &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;bl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;cl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;sil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;EXIT_SUCCESS&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Na seção de dados inicializados &lt;code&gt;.data&lt;/code&gt;, declaramos um array com 3 elementos de 1 byte cada (inteiros de 1 a 3), utilizando o número 0 como término do array:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;array&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;A seguir, na seção &lt;code&gt;.text&lt;/code&gt;, que é onde vai o código fonte do programa, podemos acessar os elementos do array utilizando aritmética de ponteiros, armazenando o resultado em registradores:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;
&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;al&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;        &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;No código acima, estamos acessando o valor contido no endereço de memória &lt;code&gt;0x402000&lt;/code&gt; e armazenando o resultado em um registrador (AL) que tem o tamanho de 1 byte, ou seja, vai ser armazenado no registrador apenas o primeiro byte do array.&lt;/p&gt;

&lt;p&gt;Vamos conferir com gdb:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="c"&gt;# O array está armazenado no endereço 0x402000&lt;/span&gt;
&lt;span class="c"&gt;# e contém o valor em hexa 0x00 0x03 0x02 0x01,&lt;/span&gt;
&lt;span class="c"&gt;# lembrando que esta arquitetura utiliza o formato little-endian&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &amp;amp;array
0x402000 &amp;lt;array&amp;gt;:       0x00030201

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; b 13
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; run
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; next

&lt;span class="c"&gt;# No registrador AL temos o primeiro elemento do array&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; i r al
al             0x1                 1

&lt;span class="c"&gt;# É o mesmo que acessar o primeiro hexabyte contido no endereço&lt;/span&gt;
&lt;span class="c"&gt;# 0x402000&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x/1xb 0x402000
0x402000 &amp;lt;array&amp;gt;:       0x01



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Lembrando que o registrador AL representa os 8-bits menores dentro do espectro do registrador RAX que contempla um total de 64-bits na arquitetura x86_64&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Para acessar os demais elementos do array, basta fazer aritmética de ponteiros e ir armazenando em outros registradores de 1 byte:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;al&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;        &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;bl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;cl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;sil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;aqui&lt;/span&gt; &lt;span class="nx"&gt;termina&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h2&gt;
  
  
  Utilizando um array com dados não inicializados
&lt;/h2&gt;

&lt;p&gt;Até agora, estamos declarando o array na seção &lt;code&gt;.data&lt;/code&gt; onde os dados são inicializados. Mas podemos deixar o programa mais "dinâmico", declarando o array na seção de dados &lt;strong&gt;não inicializados&lt;/strong&gt;, que é a &lt;code&gt;.bss&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Mantendo a compatibilidade com o exemplo anterior, vamos declarar um array de 4 bytes utilizando a diretiva &lt;code&gt;resb&lt;/code&gt; que significa "reserve byte", onde os 3 primeiros bytes são reservados para armazenar elementos do array e o último byte representando 0x0 que é o término do array.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bss&lt;/span&gt;
&lt;span class="nl"&gt;array&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;resb&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="err"&gt;é&lt;/span&gt;&lt;span class="nx"&gt;rmino&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;No gdb, podemos ver que o array está inicializado com os valores tudo a zero, o que indica que o array está vazio mas com 4 bytes reservados:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &amp;amp;array
0x402004 &amp;lt;array&amp;gt;:       0x00000000

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x/4xb &amp;amp;array
0x402004 &amp;lt;array&amp;gt;:       0x00    0x00    0x00    0x00


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Para adicionar elementos no array, precisamos também utilizar aritmética de ponteiros, tal como fizemos no exemplo anterior para acessar um array com dados pré-inicializados.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Move&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;valor&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;primeiro&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;endere&lt;/span&gt;&lt;span class="err"&gt;ç&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;mem&lt;/span&gt;&lt;span class="err"&gt;ó&lt;/span&gt;&lt;span class="nx"&gt;ria&lt;/span&gt; &lt;span class="nx"&gt;em&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;  &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Com gdb confirmamos que no endereço 0x402000 que é onde está o array, foi adicionado o byte 1:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &amp;amp;array
0x402000 &amp;lt;array&amp;gt;:       0x00000001


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;E se quisermos adicionar o valor 2 no próximo byte do array?&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &amp;amp;array
0x402000 &amp;lt;array&amp;gt;:       0x00000201


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Repare que o que modifica é o "índice" do array. Na posição inicial do array, é como se o índice fosse zero, e na posição subsequente, utilizamos o índice 1, podendo incrementar até o término array.&lt;/p&gt;

&lt;p&gt;Seria muito complicado ficar manipulando índice hard-coded. Precisamos de um &lt;em&gt;ponteiro&lt;/em&gt; para representar este índice.&lt;/p&gt;

&lt;h3&gt;
  
  
  Índice para o resgate
&lt;/h3&gt;

&lt;p&gt;Assumindo que o ponteiro do array começa com &lt;em&gt;zero&lt;/em&gt;, que é o endereço de memória onde está o array, podemos declará-lo na seção de dados inicializados &lt;code&gt;.data&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

section .bss
array: resb 4 ; 3 bytes + 1 byte de término

section .data
pointer: db 0


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Logo, poderíamos adicionar o primeiro elemento da seguinte forma, certo?&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Ao rodar o programa, temos o seguinte erro:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

src/live.asm:14: error: invalid effective address: multiple base segments


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Este erro indica que estamos tentando fazer manipulação de ponteiros a partir de múltiplos segmentos na memória&lt;/strong&gt;, no caso o array e pointer.&lt;/p&gt;

&lt;p&gt;Para resolver isto, precisamos fazer manipulação de ponteiros com valores imediatos (que foi o caso anterior com número hard-coded) ou com registradores:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;al&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;a primeira instrução move o primeiro byte contido no endereço de &lt;code&gt;pointer&lt;/code&gt; e armazena no registrador AL&lt;/li&gt;
&lt;li&gt;a segunda instrução move o valor imediato 1 (elemento do array) para o endereço de memória do array. Como em RAX (versão 64-bits de AL) temos o valor &lt;code&gt;0x0&lt;/code&gt; que representa o ponteiro, então estamos fazendo a inserção no primeiro byte do array&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;E para armazenar o segundo elemento no array?&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;al&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;No gdb, vamos verificar o que está acontecendo:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &amp;amp;array
0x402004 &amp;lt;array&amp;gt;:       0x00000002


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Uh, oh...&lt;/em&gt; Desta forma estamos sobrescrevendo o valor anterior. Queremos na verdade que o ponteiro "ande", ou seja, precisa ser incrementado em um byte para que o &lt;code&gt;append(2)&lt;/code&gt; resulte com os 2 elementos no array.&lt;/p&gt;

&lt;p&gt;Com a instrução &lt;code&gt;INC&lt;/code&gt; podemos resolver este problema:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;al&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;      &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;pointer&lt;/span&gt; &lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;          &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;pointer&lt;/span&gt; &lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;al&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &amp;amp;array
0x402004 &amp;lt;array&amp;gt;:       0x00000201


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Yay!&lt;/em&gt; Que dia maravilhoso!&lt;/p&gt;

&lt;h3&gt;
  
  
  Atingindo o limite do array
&lt;/h3&gt;

&lt;p&gt;E se continuarmos incrementando o ponteiro até atingir o limite do array?&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;al&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;al&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;al&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="c"&gt;# Lendo os primeiros 4 hexabytes do array, temos a representação&lt;/span&gt;
&lt;span class="c"&gt;# do array cheio com todos os espaços ocupados, lembrando que&lt;/span&gt;
&lt;span class="c"&gt;# o último byte é o término do array&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x /4xb &amp;amp;array
0x402004 &amp;lt;array&amp;gt;:       0x01    0x02    0x03    0x00

&lt;span class="c"&gt;# O ponteiro está no fim do array&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &amp;amp;pointer
0x402000 &amp;lt;pointer&amp;gt;:     0x03


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Maravilha, e se adicionar mais um elemento, nosso programa deveria permitir?&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;al&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="c"&gt;# Não deveríamos permitir que mais um elemento fosse adicionado,&lt;/span&gt;
&lt;span class="c"&gt;# pois nosso array já estava cheio&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x /4xb &amp;amp;array
0x402004 &amp;lt;array&amp;gt;:       0x01    0x02    0x03    0x04

&lt;span class="c"&gt;# O ponteiro está para além da capacidade array (not good...)&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &amp;amp;pointer
0x402000 &amp;lt;pointer&amp;gt;:     0x04


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Vamos utilizar um jump condicional (explico mais sobre isto na &lt;a href="https://dev.to/leandronsp/construindo-um-web-server-em-assembly-x86-parte-iv-um-assembly-modesto-oif"&gt;saga&lt;/a&gt;) para não permitir que o elemento seja adicionado. Com isto, antes de fazer o append no array, devemos verificar se o ponteiro já não está no fim do array:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;cmp&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;verifica&lt;/span&gt; &lt;span class="nx"&gt;se&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="nx"&gt;est&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;cheio&lt;/span&gt;
&lt;span class="nx"&gt;je&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt;                &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;salta&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;rotina&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt; &lt;span class="nx"&gt;caso&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;flag&lt;/span&gt; &lt;span class="nx"&gt;seja&lt;/span&gt; &lt;span class="nx"&gt;levantada&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Assim fica o programa completo:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;global&lt;/span&gt; &lt;span class="nx"&gt;_start&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;EXIT_SUCCESS&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bss&lt;/span&gt;
&lt;span class="nl"&gt;array&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;resb&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="err"&gt;é&lt;/span&gt;&lt;span class="nx"&gt;rmino&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;
&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;cmp&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;verifica&lt;/span&gt; &lt;span class="nx"&gt;se&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="nx"&gt;est&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;cheio&lt;/span&gt;
    &lt;span class="nx"&gt;je&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;al&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="nx"&gt;cmp&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;verifica&lt;/span&gt; &lt;span class="nx"&gt;se&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="nx"&gt;est&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;cheio&lt;/span&gt;
    &lt;span class="nx"&gt;je&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;al&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="nx"&gt;cmp&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;verifica&lt;/span&gt; &lt;span class="nx"&gt;se&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="nx"&gt;est&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;cheio&lt;/span&gt;
    &lt;span class="nx"&gt;je&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;al&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
    &lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="nx"&gt;cmp&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;verifica&lt;/span&gt; &lt;span class="nx"&gt;se&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="nx"&gt;est&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;cheio&lt;/span&gt;
    &lt;span class="nx"&gt;je&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="err"&gt;ã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;deveria&lt;/span&gt; &lt;span class="nx"&gt;permitir&lt;/span&gt; &lt;span class="nx"&gt;adicionar&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;quarto&lt;/span&gt; &lt;span class="nx"&gt;elemento&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;pois&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="nx"&gt;suporta&lt;/span&gt; &lt;span class="nx"&gt;at&lt;/span&gt;&lt;span class="err"&gt;é&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="nx"&gt;elementos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;desta&lt;/span&gt; &lt;span class="nx"&gt;forma&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;estar&lt;/span&gt;&lt;span class="err"&gt;í&lt;/span&gt;&lt;span class="nx"&gt;amos&lt;/span&gt; &lt;span class="nx"&gt;escrevendo&lt;/span&gt; &lt;span class="nx"&gt;no&lt;/span&gt; &lt;span class="nx"&gt;endere&lt;/span&gt;&lt;span class="err"&gt;ç&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;mem&lt;/span&gt;&lt;span class="err"&gt;ó&lt;/span&gt;&lt;span class="nx"&gt;ria&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;outros&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;dados&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;programa&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;al&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
    &lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;EXIT_SUCCESS&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &amp;amp;pointer
0x402000 &amp;lt;pointer&amp;gt;:     0x00000003
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &amp;amp;array
0x402004 &amp;lt;array&amp;gt;:       0x00030201


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Perfeito, vamos agora fazer um pequeno refactoring no código separando a lógica de append para uma subrotina:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;global&lt;/span&gt; &lt;span class="nx"&gt;_start&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;EXIT_SUCCESS&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CAPACITY&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bss&lt;/span&gt;
&lt;span class="nl"&gt;array&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;resb&lt;/span&gt; &lt;span class="nx"&gt;CAPACITY&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;
&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;EXIT_SUCCESS&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;cmp&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;CAPACITY&lt;/span&gt; &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;verifica&lt;/span&gt; &lt;span class="nx"&gt;se&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="nx"&gt;est&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;cheio&lt;/span&gt;
    &lt;span class="nx"&gt;je&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;al&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;dil&lt;/span&gt;
    &lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Se você quer entender mais sobre conditional jump, rotinas, call, ret e flags, sugiro a leitura da minha saga que foi referenciada diversas vezes neste artigo&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Executando com gdb e...&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &amp;amp;array
0x402004 &amp;lt;array&amp;gt;:       0x00030201

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &amp;amp;pointer
0x402000 &amp;lt;pointer&amp;gt;:     0x00000003


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Um grande &lt;em&gt;Yay!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Entretanto, podem haver situações onde queremos que nosso array seja &lt;em&gt;redimensionado&lt;/em&gt; para suportar mais elementos, ou seja, o tamanho do array seria dinâmico. &lt;/p&gt;

&lt;p&gt;Como adicionar mais elementos além da &lt;em&gt;capacidade inicial&lt;/em&gt; de forma que não podemos escrever em outras áreas da memória que pertencem ao array?&lt;/p&gt;




&lt;h2&gt;
  
  
  Heap, heap, hooray!
&lt;/h2&gt;

&lt;p&gt;Antes de falar sobre o heap, vamos relembrar como funciona o layout de memória de um programa de computador:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs81vxvgfylw0wfcf6if7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs81vxvgfylw0wfcf6if7.png" alt="layout de memória"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;o layout é representado como uma área na memória do computador onde temos os endereços de memória mais baixos do programa em direção aos endereços mais altos que ficam no topo&lt;/li&gt;
&lt;li&gt;nos endereços de memória mais baixos, temos a seção &lt;code&gt;.text&lt;/code&gt;, onde já vimos que é referente ao programa em si&lt;/li&gt;
&lt;li&gt;depois temos a &lt;strong&gt;seção de dados&lt;/strong&gt; que contempla os dados inicializados &lt;code&gt;.data&lt;/code&gt; e a seção a seguir que representa os dados não-inicializados &lt;code&gt;.bss&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;nos endereços mais altos, temos a &lt;em&gt;stack&lt;/em&gt; do programa, que armazena metadados tais como o nome do programa, seus argumentos e qualquer informação do programa que tenha um tamanho fixo cabendo dentro da stack, bem como chamadas de funções e seus respectivos argumentos&lt;/li&gt;
&lt;li&gt;a stack tem um formato de &lt;em&gt;pilha&lt;/em&gt; e "cresce pra baixo", ou seja, conforme adicionamos elementos na stack, esta cresce em direção aos endereços mais baixos na memória&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No "meio" do layout, entre a seção de dados e a stack, temos uma grande área na memória que muitos acabam associando como &lt;em&gt;heap&lt;/em&gt;. No heap, podemos alocar dados de forma dinâmica, diferente da forma estática que fazemos na seção de dados.&lt;/p&gt;

&lt;p&gt;Para acomodar um array de tamanho dinâmico que suporte redimensionamento (resize), temos de alocar memória nesta área.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Neste artigo, vamos chamar esta região no meio da memória que fica entre a seção de dados e a stack de &lt;strong&gt;heap&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Alocação dinâmica de memória com brk
&lt;/h3&gt;

&lt;p&gt;Uma das formas de manipular esta área da memória é através da &lt;a href="https://man7.org/linux/man-pages/man2/brk.2.html" rel="noopener noreferrer"&gt;syscall brk&lt;/a&gt;, que muda o &lt;em&gt;program break&lt;/em&gt;, que é &lt;strong&gt;onde termina a seção de dados&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3c703vs0c7bl1eosh5i8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3c703vs0c7bl1eosh5i8.png" alt="program break"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com &lt;code&gt;brk&lt;/code&gt;, podemos modificar esse &lt;em&gt;program break&lt;/em&gt; para endereços mais altos, ou seja, permitindo a manipulação de áreas na memória que vão além da seção de programa e dados.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjh2x79f2nb1m1v4dcaxe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjh2x79f2nb1m1v4dcaxe.png" alt="program break visualizado"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A primeira coisa que precisamos fazer é mapear a syscall e fazer a chamada que traz o endereço do break atual:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;
&lt;span class="p"&gt;....&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;
&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;syscall&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;acessar&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;program&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0x403000&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;que&lt;/span&gt; &lt;span class="err"&gt;é&lt;/span&gt; &lt;span class="nx"&gt;onde&lt;/span&gt; &lt;span class="nx"&gt;termina&lt;/span&gt; 
&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;se&lt;/span&gt;&lt;span class="err"&gt;çã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;dados&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="nx"&gt;come&lt;/span&gt;&lt;span class="err"&gt;ç&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;heap&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt;
&lt;span class="nx"&gt;syscall&lt;/span&gt;
&lt;span class="p"&gt;....&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Com gdb, vamos analisar o estado do programa:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="c"&gt;# Breakpoint na linha da syscall brk&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; b 18
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; run

&lt;span class="c"&gt;# O início do programa fica na seção .text e começa com &lt;/span&gt;
&lt;span class="c"&gt;# 0x401000&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x _start
0x401000 &amp;lt;_start&amp;gt;:      0x000000bf

&lt;span class="c"&gt;# O pointer está na seção .data um pouco mais acima e começa com&lt;/span&gt;
&lt;span class="c"&gt;# 0x402000&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &amp;amp;pointer
0x402000 &amp;lt;pointer&amp;gt;:     0x00000000

&lt;span class="c"&gt;# O array está na seção .bss um pouco mais acima e começa com &lt;/span&gt;
&lt;span class="c"&gt;# 0x402004&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &amp;amp;array
0x402004 &amp;lt;array&amp;gt;:       0x00000000

&lt;span class="c"&gt;# Executa a syscall brk&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; n

&lt;span class="c"&gt;# A syscall brk armazena em RAX o endereço de memória do program break, &lt;/span&gt;
&lt;span class="c"&gt;# no caso um pouco mais acima em 0x403000&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; i r rax
rax            0x403000            4206592


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;0x401000&lt;/code&gt;: seção &lt;code&gt;.text&lt;/code&gt; que é onde começa o programa&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;0x402000&lt;/code&gt;: seção &lt;code&gt;.data&lt;/code&gt; onde ficam os dados inicializados&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;0x402004&lt;/code&gt;: seção &lt;code&gt;.bss&lt;/code&gt; onde ficam os dados não-inicializados&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;0x403000&lt;/code&gt;: program break, que é onde termina a seção de dados e começa o nosso "heap"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Com isto, a partir do endereço &lt;code&gt;0x403000&lt;/code&gt; é onde vamos colocar os elementos do nosso array, pelo que o endereço do array pode utilizar apenas um byte, que aponta para o endereço onde começa o primeiro elemento no heap.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmkuui4ot8ta2ohpf05bx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmkuui4ot8ta2ohpf05bx.png" alt="array no heap"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Na syscall que fizemos, se o argumento em RDI tiver zero, significa que brk vai retornar o program break atual, no caso &lt;code&gt;0x403000&lt;/code&gt;. Mas podemos fazer mais syscalls brk com o argumento RDI diferente (incrementado), sinalizando que estamos mudando o program break.&lt;/p&gt;

&lt;p&gt;A partir de agora, na seção de dados &lt;code&gt;.bss&lt;/code&gt;, não precisamos mais reservar 4 bytes para o array, pelo que é necessário apenas 1 byte que irá representar o endereço de memória do array no heap:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;global&lt;/span&gt; &lt;span class="nx"&gt;_start&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;EXIT_SUCCESS&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CAPACITY&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;

&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;inicialmente&lt;/span&gt; &lt;span class="nx"&gt;come&lt;/span&gt;&lt;span class="err"&gt;ç&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;com&lt;/span&gt; &lt;span class="mh"&gt;0x000000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mas&lt;/span&gt; &lt;span class="nx"&gt;depois&lt;/span&gt; &lt;span class="nx"&gt;ir&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;conter&lt;/span&gt; 
&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;endere&lt;/span&gt;&lt;span class="err"&gt;ç&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="mh"&gt;0x403000&lt;/span&gt;
&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bss&lt;/span&gt;
&lt;span class="nl"&gt;array&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;resb&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;  

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;
&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;
    &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CAPACITY&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Ao analisarmos com gdb:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="c"&gt;# Breakpoint na primeira syscall&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; b 18

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; run

&lt;span class="c"&gt;# Executa a linha da syscall&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; n

&lt;span class="c"&gt;# Em RAX a syscall armazena o endereço do program break, no caso&lt;/span&gt;
&lt;span class="c"&gt;# 0x403000&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; i r rax
rax            0x403000            4206592

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x 0x403000
0x403000:       Cannot access memory at address 0x403000


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Neste momento, este endereço ainda não é acessível pois não reservamos novos bytes no heap. Vamos andar com a próxima syscall:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; n
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; n

&lt;span class="c"&gt;# Antes de executar a syscall, verificamos que o argumento RDI vai &lt;/span&gt;
&lt;span class="c"&gt;# conter o endereço desejado para o novo program break, no caso com&lt;/span&gt;
&lt;span class="c"&gt;# 3 bytes adicionados, 0x403003&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; i r rdi
rdi            0x403003            4206595

&lt;span class="c"&gt;# Executa a syscall...&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; n
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; n

&lt;span class="c"&gt;# Após a execução da segunda syscall, vemos que em RAX, o program break foi alterado para 0x403003&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; i r rax
rax            0x403003            4206595


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Agora, podemos acessar os endereços de memória entre &lt;code&gt;0x403000&lt;/code&gt; e &lt;code&gt;0x403003&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x 0x403000
0x403000:       0x00000000
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x 0x403001
0x403001:       0x00000000
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x 0x403002
0x403002:       0x00000000
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x 0x403003
0x403003:       0x00000000


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Uau!&lt;/em&gt; Agora temos no heap uma área reservada especialmente para o nosso querido array, olha que coisa!&lt;/p&gt;

&lt;p&gt;Como vamos manipular o array nesta região da memória?&lt;/p&gt;

&lt;h3&gt;
  
  
  Ponteiros, ponteiros everywhere
&lt;/h3&gt;

&lt;p&gt;Após a primeira syscall, devemos pegar o endereço de memória &lt;code&gt;0x403000&lt;/code&gt; que representa o primeiro program break e armazenar no ponteiro do array que está em &lt;code&gt;.bss&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt;
&lt;span class="nx"&gt;syscall&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;      &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;----&lt;/span&gt; &lt;span class="nx"&gt;breakpoint&lt;/span&gt; &lt;span class="nx"&gt;aqui&lt;/span&gt;

&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;
&lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CAPACITY&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt;
&lt;span class="nx"&gt;syscall&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Vamos verificar com gdb o breakpoint na linha que muda o ponteiro do array:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; b 19
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; run

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &amp;amp;array
0x402004 &amp;lt;array&amp;gt;:       0x00000000

&lt;span class="c"&gt;# Executa a linha que muda o ponteiro&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; n

&lt;span class="c"&gt;# Agora o ponteiro aponta para o endereço 0x403000, &lt;/span&gt;
&lt;span class="c"&gt;# é isto o que queremos&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &amp;amp;array
0x402004 &amp;lt;array&amp;gt;:       0x00403000


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Importante notar&lt;/em&gt; que &lt;strong&gt;array&lt;/strong&gt; está no endereço &lt;code&gt;0x402004&lt;/code&gt;, na seção &lt;code&gt;.bss&lt;/code&gt;, pelo que seu valor representa outro endereço de memória &lt;code&gt;0x403000&lt;/code&gt; que é onde deve começar o primeiro elemento do array no heap.&lt;/p&gt;

&lt;p&gt;Agora, quando fizermos a próxima syscall para alocar 3 bytes no heap, o program break será modificado e iremos conseguir manipular o array pois o ponteiro já aponta para o endereço correto.&lt;/p&gt;

&lt;p&gt;Após a segunda syscall, já não podemos mais manipular o &lt;code&gt;array&lt;/code&gt; pelo seu valor, pois agora o valor do array já não é mais um elemento de fato, mas sim um endereço para outro lugar na memória.&lt;/p&gt;

&lt;p&gt;Vamos ao programa na versão atual:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;global&lt;/span&gt; &lt;span class="nx"&gt;_start&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;EXIT_SUCCESS&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CAPACITY&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bss&lt;/span&gt;
&lt;span class="nl"&gt;array&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;resb&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="mh"&gt;0x403000&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;
&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;
    &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CAPACITY&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rbx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;EXIT_SUCCESS&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;cmp&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;CAPACITY&lt;/span&gt; &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;verifica&lt;/span&gt; &lt;span class="nx"&gt;se&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="nx"&gt;est&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;cheio&lt;/span&gt;
    &lt;span class="nx"&gt;je&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;sil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rbx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;r8b&lt;/span&gt;
    &lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Explicando cada bloco:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt;
&lt;span class="nx"&gt;syscall&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;busca o program break atual e armazena o endereço no ponteiro &lt;code&gt;array&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;
&lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CAPACITY&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt;
&lt;span class="nx"&gt;syscall&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;modifica o program break atual, incrementando 3 bytes que é a capacidade inicial do array no heap&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;atribuir&lt;/span&gt; &lt;span class="nx"&gt;ao&lt;/span&gt; &lt;span class="nx"&gt;registrador&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;endere&lt;/span&gt;&lt;span class="err"&gt;ç&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;mem&lt;/span&gt;&lt;span class="err"&gt;ó&lt;/span&gt;&lt;span class="nx"&gt;ria&lt;/span&gt; &lt;span class="nx"&gt;ao&lt;/span&gt; &lt;span class="nx"&gt;qual&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt;
&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;ponteiro&lt;/span&gt; &lt;span class="s2"&gt;"array"&lt;/span&gt; &lt;span class="nx"&gt;est&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;apontando&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rbx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; 


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;armazena o endereço de memória do ponteiro no registrador RBX. Isto é necessário pois não queremos fazer aritmética diretamente no ponteiro da seção &lt;code&gt;.bss&lt;/code&gt;, mas sim através de um registrador que permite &lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;como agora o RDI foi usado como argumento na syscall brk, não convém mais utilizarmos este registrador para representar o elemento a ser adicionado no array, pelo que trocamos pelo registrador R8&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;cmp&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;CAPACITY&lt;/span&gt; &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;verifica&lt;/span&gt; &lt;span class="nx"&gt;se&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="nx"&gt;est&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;cheio&lt;/span&gt;
    &lt;span class="nx"&gt;je&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;sil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rbx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;r8b&lt;/span&gt;    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;indirect&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;mode&lt;/span&gt; &lt;span class="nx"&gt;addressing&lt;/span&gt;
    &lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Agora a rotina &lt;code&gt;.append&lt;/code&gt; foi modificado para que a manipulação do array no heap seja através do registrador RBX. Também não podemos mais usar o registrador RAX para representar o ponteiro pois a syscall brk também utilizou como retorno do program break; neste caso trocamos para o RSI (que tem o SIL como sua representação de 8-bits menores).&lt;/p&gt;

&lt;p&gt;Ao executar com gdb, podemos verificar que os elementos estão sendo adicionados no endereço &lt;code&gt;0x403000&lt;/code&gt; que fica no heap, através do ponteiro que foi armazenado no registrador RBX:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="c"&gt;# Array aponta para o endereço 0x403000&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &amp;amp;array
0x402004 &amp;lt;array&amp;gt;:       0x00403000

&lt;span class="c"&gt;# No endereço, temos os elementos adicionados. Yay!&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x 0x403000
0x403000:       0x00030201

&lt;span class="c"&gt;# E o ponteiro de "índice" corretamente representando o fim do array no heap&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &amp;amp;pointer
0x402000 &amp;lt;pointer&amp;gt;:     0x00000003


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Neste momento, o programa está com o mesmo comportamento do exemplo anterior com array estático em &lt;code&gt;.bss&lt;/code&gt;, não permitindo adicionar mais elementos quando o array atinge seu limite.&lt;/p&gt;

&lt;p&gt;Vamos mudar isto, redimensionando o array e permitir que novos elementos sejam adicionados.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resize com brk
&lt;/h3&gt;

&lt;p&gt;A seguir, iniciamos os passos para que o redimensionamento do array seja feito quando &lt;strong&gt;este atingir o limite da capacidade&lt;/strong&gt;. Começamos por alterar a rotina &lt;code&gt;.append&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;cmp&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;CAPACITY&lt;/span&gt; &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;verifica&lt;/span&gt; &lt;span class="nx"&gt;se&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="nx"&gt;est&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;cheio&lt;/span&gt;
    &lt;span class="nx"&gt;je&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resize&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;sil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rbx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;r8b&lt;/span&gt;
    &lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resize&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Ao invés de fazer jump para &lt;code&gt;.done&lt;/code&gt; quando o array estiver cheio, fazemos jump para outra sub-rotina chamada &lt;code&gt;.resize&lt;/code&gt;, que deverá fazer a syscall brk novamente, modificando assim o &lt;strong&gt;program break&lt;/strong&gt; em uma nova área na memória, obedecendo a capacidade inicial do array:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;cmp&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;CAPACITY&lt;/span&gt; &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;verifica&lt;/span&gt; &lt;span class="nx"&gt;se&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="nx"&gt;est&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;cheio&lt;/span&gt;
    &lt;span class="nx"&gt;je&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resize&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;sil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rbx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;r8b&lt;/span&gt;
    &lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resize&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;            &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;RDI&lt;/span&gt; &lt;span class="nx"&gt;passa&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;representar&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="nx"&gt;atual&lt;/span&gt;
    &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CAPACITY&lt;/span&gt;       &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;adiciona&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ficando&lt;/span&gt; &lt;span class="mh"&gt;0x403006&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;jmp&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;a primeira syscall de resize traz o break atual, no caso já sabemos que é &lt;code&gt;0x403003&lt;/code&gt;, que foi alocado no início do programa para o array&lt;/li&gt;
&lt;li&gt;a segunda syscall de resize modifica o break atual, alocando assim mais 3 bytes no heap&lt;/li&gt;
&lt;li&gt;ao fim do resize, ao invés de retornar a função, vamos voltar para o início do &lt;code&gt;.append&lt;/code&gt; e executar a lógica necessária para adicionar o elemento no array&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Desta forma, podemos manipular esta nova área na memória para adicionar mais elementos no array, modificando assim sua capacidade dinamicamente.&lt;/p&gt;

&lt;p&gt;Se executarmos o programa exatamente assim, vamos enfrentar um problema, pois:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a cada vez que é feito o resize, salta para o início da rotina&lt;/li&gt;
&lt;li&gt;é verificado o tamanho do array (pointeiro) com a capacidade inicial, que no caso é 3. Como o ponteiro atingiu o valor 3, então vai entrar novamente no resize caracterizando assim um loop infinito com resize infinito até acabar a memória&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para resolver isto, precisamos comparar o pointer com a capacidade atual (modificada), e portanto vamos adicionar um valor na seção &lt;code&gt;.data&lt;/code&gt; que representa a capacidade atual:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CAPACITY&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="nl"&gt;currentCapacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="nx"&gt;CAPACITY&lt;/span&gt; &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;come&lt;/span&gt;&lt;span class="err"&gt;ç&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;com&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Na rotina &lt;code&gt;.append&lt;/code&gt;, vamos fazer a comparação com o &lt;code&gt;currentCapacity&lt;/code&gt;, que vai ser modificado a cada resize, ao invés de ser com &lt;code&gt;CAPACITY&lt;/code&gt;, que vai permanecer fixo com o valor inicial enquanto durar o programa.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;currentCapacity&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;cmp&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;r9b&lt;/span&gt;     &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;verifica&lt;/span&gt; &lt;span class="nx"&gt;se&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="nx"&gt;est&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;cheio&lt;/span&gt;
    &lt;span class="nx"&gt;je&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resize&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;E, após o redimensionamento antes de voltar pro &lt;code&gt;.append&lt;/code&gt;, vamos incrementar o valor da capacidade inicial à capacidade atual:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resize&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;
    &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CAPACITY&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currentCapacity&lt;/span&gt;
    &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;r10&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;CAPACITY&lt;/span&gt;
    &lt;span class="nx"&gt;jmp&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Ao executar o programa, podemos ver que o elemento 4 foi adicionado com sucesso no array após o redimensionamento:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x 0x403000
0x403000:       0x04030201


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;E se adicionarmos mais e mais elementos?&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="c"&gt;# Podemos ver que o currentCapacity é 9, ou seja, foram feitos &lt;/span&gt;
&lt;span class="c"&gt;# 2 redimensionamentos. Nosso array consegue agora acomodar até 9 elementos, &lt;/span&gt;
&lt;span class="c"&gt;# pelo que ao adicionar o décimo elemento, mais um resize seria feito.&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &amp;amp;currentCapacity
0x402001 &amp;lt;currentCapacity&amp;gt;:     0x09

&lt;span class="c"&gt;# Buscando os 9 primeiros hexabytes no endereço do array no heap&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x/9xb  0x403000
0x403000:       0x01    0x02    0x03    0x04    0x05    0x06    0x07    0x00
0x403008:       0x00


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;How cool is that?&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  O programa final
&lt;/h2&gt;

&lt;p&gt;A seguir o programa final, com um array de capacidade inicial de 3 elementos no heap que pode ser redimensionado utilizando a syscall &lt;code&gt;brk&lt;/code&gt;, conforme mais elementos vão sendo adicionados no array:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;global&lt;/span&gt; &lt;span class="nx"&gt;_start&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;EXIT_SUCCESS&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CAPACITY&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bss&lt;/span&gt;
&lt;span class="nl"&gt;array&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;resb&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="nl"&gt;currentCapacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="nx"&gt;CAPACITY&lt;/span&gt; &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;capacidade&lt;/span&gt; &lt;span class="nx"&gt;inicial&lt;/span&gt; &lt;span class="err"&gt;é&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;
&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;
    &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CAPACITY&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rbx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;EXIT_SUCCESS&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;currentCapacity&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;cmp&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;r9b&lt;/span&gt; &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;verifica&lt;/span&gt; &lt;span class="nx"&gt;se&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="nx"&gt;est&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;cheio&lt;/span&gt;
    &lt;span class="nx"&gt;je&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resize&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;sil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rbx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;r8b&lt;/span&gt;
    &lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resize&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;
    &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CAPACITY&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currentCapacity&lt;/span&gt;
    &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;r10&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;CAPACITY&lt;/span&gt;
    &lt;span class="nx"&gt;jmp&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Neste artigo, mostramos a implementação de um array em Assembly x86, passando por conceitos importantes como layout de memória, manipulação de registradores e alocação dinâmica de memória com &lt;code&gt;brk&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Este artigo é base para artigos futuros sobre estruturas de dados, onde pretendo escrever sobre a implementação de filas e posteriormente listas ligadas.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Stay tuned!&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;p&gt;&lt;br&gt;
Addressing modes&lt;br&gt;
&lt;a href="https://www.tutorialspoint.com/assembly_programming/assembly_addressing_modes.htm" rel="noopener noreferrer"&gt;https://www.tutorialspoint.com/assembly_programming/assembly_addressing_modes.htm&lt;/a&gt;&lt;br&gt;
Syscall brk&lt;br&gt;
&lt;a href="https://man7.org/linux/man-pages/man2/brk.2.html" rel="noopener noreferrer"&gt;https://man7.org/linux/man-pages/man2/brk.2.html&lt;/a&gt;&lt;br&gt;
ASCII table&lt;br&gt;
&lt;a href="https://www.asciicharstable.com/_site_media/ascii/ascii-chars-table-landscape.jpg" rel="noopener noreferrer"&gt;https://www.asciicharstable.com/_site_media/ascii/ascii-chars-table-landscape.jpg&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

</description>
      <category>assembly</category>
      <category>computerscience</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Construindo um web server em Assembly x86, the grand finale, multi-threading</title>
      <dc:creator>Leandro Proença</dc:creator>
      <pubDate>Sun, 14 Jul 2024 02:37:25 +0000</pubDate>
      <link>https://dev.to/leandronsp/construindo-um-web-server-em-assembly-x86-the-grand-finale-multi-threading-24hp</link>
      <guid>https://dev.to/leandronsp/construindo-um-web-server-em-assembly-x86-the-grand-finale-multi-threading-24hp</guid>
      <description>&lt;p&gt;Uma vez que temos um &lt;a href="https://dev.to/leandronsp/construindo-um-web-server-em-assembly-x86-parte-v-finalmente-o-server-9e5"&gt;web server funcional&lt;/a&gt;, podemos dar o próximo (e último) passo, que é deixar o servidor &lt;strong&gt;minimamente escalável&lt;/strong&gt; fazendo uso de uma pool de threads. &lt;/p&gt;

&lt;p&gt;Neste artigo, vamos mergulhar nas entranhas da implementação de uma pool de threads com sincronização através de locks, e para atingir tal feito em assembly abordaremos filas, alocação dinâmica de memória e controle de locks com futex.&lt;/p&gt;

&lt;p&gt;Ao fim deste artigo, que é o último da saga, teremos uma visão mais holística sobre como funciona um web server e como uma pool de threads poderia ser implementada em linguagens de baixo nível.&lt;/p&gt;

&lt;p&gt;Respira e vem comigo, esta última parte será uma avalanche de conceitos.&lt;/p&gt;




&lt;h2&gt;
  
  
  Agenda
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Simulando a latência com nanosleep&lt;/li&gt;
&lt;li&gt;Simulando requests em escala com xargs&lt;/li&gt;
&lt;li&gt;Concorrência com forking de processos&lt;/li&gt;
&lt;li&gt;Concorrência com clone de processo&lt;/li&gt;
&lt;li&gt;
Concorrência com threads

&lt;ul&gt;
&lt;li&gt;Entendendo a criação de uma thread&lt;/li&gt;
&lt;li&gt;Thread flags&lt;/li&gt;
&lt;li&gt;Alocação de memória com brk&lt;/li&gt;
&lt;li&gt;Modificando o server para suportar multi-threading&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Concorrência com thread pool

&lt;ul&gt;
&lt;li&gt;Uma thread em loop&lt;/li&gt;
&lt;li&gt;5 threads em loop&lt;/li&gt;
&lt;li&gt;Sincronização com futex&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Alocação de memória com mmap&lt;/li&gt;

&lt;li&gt;Conclusão&lt;/li&gt;

&lt;li&gt;Referências&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  Simulando a latência com nanosleep
&lt;/h2&gt;

&lt;p&gt;Quando uma requisição é feita a um web server, o tempo de resposta total é um somatório de toda a latência envolvida na comunicação, desde o momento em que o pedido sai da origem (client), passando pela rede de computadores (internet), chegando no destino (server), &lt;strong&gt;sendo processado&lt;/strong&gt;, para então a resposta fazer o caminho inverso até voltar ao client.&lt;/p&gt;

&lt;p&gt;Quanto maior a latência em qualquer parte do processo, maior o tempo de resposta, e portanto menor a capacidade de entregar respostas de diferentes requisições em um determinado intervalo de tempo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F89cfxfykz32gd02sdjci.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F89cfxfykz32gd02sdjci.png" alt="server-database" width="538" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A esta capacidade de processar requisições em um intervalo de tempo chamamos de &lt;strong&gt;throughput&lt;/strong&gt;. O que queremos no fim das contas é &lt;em&gt;aumentar o throughput sem comprometer a latência&lt;/em&gt;. Esta é uma das premissas para sistemas escaláveis, mas o foco deste artigo não será em escalabilidade necessariamente.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No artigo anterior, finalizamos o web server que apenas responde no socket uma mensagem HTML contendo "Hello, world". A seguir o código inicial do server, que será a base para o restante do artigo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;global&lt;/span&gt; &lt;span class="nx"&gt;_start&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_socket&lt;/span&gt; &lt;span class="mi"&gt;41&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_bind&lt;/span&gt; &lt;span class="mi"&gt;49&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_listen&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_accept4&lt;/span&gt; &lt;span class="mi"&gt;288&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_close&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;AF_INET&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SOCK_STREAM&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SOCK_PROTOCOL&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;BACKLOG&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CR&lt;/span&gt; &lt;span class="mh"&gt;0xD&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;LF&lt;/span&gt; &lt;span class="mh"&gt;0xA&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;sockaddr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nl"&gt;sa_family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dw&lt;/span&gt; &lt;span class="nx"&gt;AF_INET&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt;
    &lt;span class="nl"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dw&lt;/span&gt; &lt;span class="mh"&gt;0xB80B&lt;/span&gt;         &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt;
    &lt;span class="nl"&gt;ip_addr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dd&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;           &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt;
    &lt;span class="nl"&gt;sin_zero&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dq&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;          &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt;
&lt;span class="nl"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
    &lt;span class="nl"&gt;headline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"HTTP/1.1 200 OK"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;LF&lt;/span&gt;
    &lt;span class="nl"&gt;content_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: text/html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;LF&lt;/span&gt;
    &lt;span class="nl"&gt;content_length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"Content-Length: 22"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;LF&lt;/span&gt;
    &lt;span class="nl"&gt;crlf&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="nx"&gt;CR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;LF&lt;/span&gt;
    &lt;span class="nl"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;"&lt;/span&gt;
&lt;span class="nl"&gt;responseLen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;equ&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bss&lt;/span&gt;
&lt;span class="nl"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;resb&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;
&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;AF_INET&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SOCK_STREAM&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SOCK_PROTOCOL&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_socket&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bind&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;struct&lt;/span&gt; &lt;span class="nx"&gt;sockaddr&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;socklen_t&lt;/span&gt; &lt;span class="nx"&gt;addrlen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sockaddr&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_bind&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;backlog&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;BACKLOG&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_listen&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accept&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;struct&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;addrlen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_accept4&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="nx"&gt;handle&lt;/span&gt;
    &lt;span class="nx"&gt;jmp&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accept&lt;/span&gt;
&lt;span class="nl"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;responseLen&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_close&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Até aqui tudo normal. A rotina &lt;code&gt;accept&lt;/code&gt; fica em loop chamando a rotina &lt;code&gt;handle&lt;/code&gt; que escreve "Hello, world" na resposta de cada requisição que chega no socket.&lt;/p&gt;

&lt;p&gt;Com &lt;em&gt;strace&lt;/em&gt;, podemos ver as chamadas que foram feitas após uma requisição com &lt;em&gt;curl&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;socket&lt;span class="o"&gt;(&lt;/span&gt;AF_INET, SOCK_STREAM, IPPROTO_IP&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 3
&lt;span class="nb"&gt;bind&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;3, &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;sa_family&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;AF_INET, &lt;span class="nv"&gt;sin_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;htons&lt;span class="o"&gt;(&lt;/span&gt;3000&lt;span class="o"&gt;)&lt;/span&gt;, &lt;span class="nv"&gt;sin_addr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;inet_addr&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"0.0.0.0"&lt;/span&gt;&lt;span class="o"&gt;)}&lt;/span&gt;, 16&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 0
listen&lt;span class="o"&gt;(&lt;/span&gt;3, 2&lt;span class="o"&gt;)&lt;/span&gt;                            &lt;span class="o"&gt;=&lt;/span&gt; 0
accept4&lt;span class="o"&gt;(&lt;/span&gt;3, NULL, NULL, 0&lt;span class="o"&gt;)&lt;/span&gt;               &lt;span class="o"&gt;=&lt;/span&gt; 4
write&lt;span class="o"&gt;(&lt;/span&gt;4, &lt;span class="s2"&gt;"HTTP/1.1 200 OK&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s2"&gt;Content-Type: t"&lt;/span&gt;..., 86&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 86
close&lt;span class="o"&gt;(&lt;/span&gt;4&lt;span class="o"&gt;)&lt;/span&gt;                                &lt;span class="o"&gt;=&lt;/span&gt; 0
accept4&lt;span class="o"&gt;(&lt;/span&gt;3, NULL, NULL, 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;socket&lt;/strong&gt;, bind, listen, para então iniciar o &lt;strong&gt;accept&lt;/strong&gt;, que ao receber uma requisição HTTP, passa para &lt;strong&gt;write&lt;/strong&gt;, &lt;strong&gt;close&lt;/strong&gt; e então voltar ao &lt;strong&gt;accept&lt;/strong&gt; novamente em loop.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Para simular um pouco de latência, vamos fazer com que a resposta demore cerca de 1 segundo, e para tanto precisamos utilizar uma syscall no Linux chamada &lt;code&gt;nanosleep&lt;/code&gt;, que suspende a execução da thread atual até atingir um tempo decorrido especificado com base no relógio monotônico do sistema:&lt;/p&gt;

&lt;p&gt;Primeiro definimos a syscall, que tem o código 35:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_nanosleep&lt;/span&gt; &lt;span class="mi"&gt;35&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Na rotina &lt;code&gt;handle&lt;/code&gt;, antes de escrever a resposta no socket, fazemos a chamada de sistema para &lt;strong&gt;nanosleep&lt;/strong&gt; passando como argumento uma struct que representa um &lt;em&gt;timespec&lt;/em&gt;, que contempla o tempo decorrido em segundos e nano-segundos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;handle&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;nanosleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timespec&lt;/span&gt; &lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;lea&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;timespec&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_nanosleep&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E na seção de dados, definimos o tempo decorrido em segundos, que são os primeiros 8 bytes da struct, deixando a &lt;em&gt;zero&lt;/em&gt; os 8 bytes restantes que representam o tempo em nano-segundos&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;timespec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nl"&gt;tv_sec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dq&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="nl"&gt;tv_nsec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dq&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Neste exemplo queremos que o sleep seja de 1 segundo&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Com &lt;em&gt;strace&lt;/em&gt;, podemos ver que a syscall &lt;code&gt;nanosleep&lt;/code&gt; foi executada após o &lt;strong&gt;accept&lt;/strong&gt; e antes do &lt;strong&gt;write&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;socket&lt;span class="o"&gt;(&lt;/span&gt;AF_INET, SOCK_STREAM, IPPROTO_IP&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 3
&lt;span class="nb"&gt;bind&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;3, &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;sa_family&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;AF_INET, &lt;span class="nv"&gt;sin_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;htons&lt;span class="o"&gt;(&lt;/span&gt;3000&lt;span class="o"&gt;)&lt;/span&gt;, &lt;span class="nv"&gt;sin_addr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;inet_addr&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"0.0.0.0"&lt;/span&gt;&lt;span class="o"&gt;)}&lt;/span&gt;, 16&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 0
listen&lt;span class="o"&gt;(&lt;/span&gt;3, 2&lt;span class="o"&gt;)&lt;/span&gt;                            &lt;span class="o"&gt;=&lt;/span&gt; 0

accept4&lt;span class="o"&gt;(&lt;/span&gt;3, NULL, NULL, 0&lt;span class="o"&gt;)&lt;/span&gt;               &lt;span class="o"&gt;=&lt;/span&gt; 4
nanosleep&lt;span class="o"&gt;({&lt;/span&gt;&lt;span class="nv"&gt;tv_sec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1, &lt;span class="nv"&gt;tv_nsec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0&lt;span class="o"&gt;}&lt;/span&gt;, NULL&lt;span class="o"&gt;)&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; 0
write&lt;span class="o"&gt;(&lt;/span&gt;4, &lt;span class="s2"&gt;"HTTP/1.1 200 OK&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s2"&gt;Content-Type: t"&lt;/span&gt;..., 86&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 86

close&lt;span class="o"&gt;(&lt;/span&gt;4&lt;span class="o"&gt;)&lt;/span&gt;                                &lt;span class="o"&gt;=&lt;/span&gt; 0
accept4&lt;span class="o"&gt;(&lt;/span&gt;3, NULL, NULL, 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Calculando o tempo decorrido com o utilitário &lt;code&gt;time&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;time &lt;/span&gt;curl localhost:3000

&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;
real    0m1.040s
user    0m0.005s
sys     0m0.009s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Podemos também encurtar a resposta do time trazendo apenas o tempo real, exportando a variável na sessão shell atual ou adicionando no &lt;code&gt;bashrc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;TIMEFORMAT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;%R

&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;time &lt;/span&gt;curl localhost:3000
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.036
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Yay!&lt;/em&gt; Já conseguimos simular uma latência de 1 segundo em Assembly. Agora vamos ver se nosso web server tem a capacidade de atender a &lt;strong&gt;requests em escala&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Simulando requests em escala com xargs
&lt;/h2&gt;

&lt;p&gt;Para começar, vamos simular 10 requests sequenciais com curl. Poderíamos ficar digitando &lt;code&gt;curl localhost:3000&lt;/code&gt; 10 vezes, ou então ser pragmáticos, automatizar sem reinventar a roda e nem instalar nada adicional no sistema.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Como?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;xargs.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;xargs&lt;/strong&gt; é um utilitário presente na maioria dos sistemas operacionais UNIX-like, que lê strings a partir de arquivos ou standard input e utiliza estas strings como argumentos para comandos arbitrários.&lt;/p&gt;

&lt;p&gt;Vamos ter como exemplo uma sequência de 1 a 10 em bash:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;1&lt;/span&gt;&lt;span class="p"&gt;..10&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
1 2 3 4 5 6 7 8 9 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Podemos utilizar cada valor do &lt;strong&gt;echo&lt;/strong&gt; como argumento para o xargs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;1..10&lt;span class="o"&gt;}&lt;/span&gt; | xargs &lt;span class="nt"&gt;-n1&lt;/span&gt;
1
2
3
4
5
6
7
8
9
10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A opção &lt;code&gt;-n1&lt;/code&gt; significa a quantidade de argumentos que serão usados para o comando que vem a seguir ao xargs, que no caso queremos apenas 1 argumento, o que neste caso tanto faz pois não queremos fazer nada com o argumento: queremos apenas executar o comando &lt;strong&gt;curl&lt;/strong&gt; 10 vezes.&lt;/p&gt;

&lt;p&gt;Podemos então agora executar o &lt;strong&gt;curl&lt;/strong&gt; com o time para saber o tempo decorrido de cada request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;time echo&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;1..10&lt;span class="o"&gt;}&lt;/span&gt; | xargs &lt;span class="nt"&gt;-n1&lt;/span&gt; bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"time curl localhost:3000"&lt;/span&gt;

&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.037
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.033
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.025
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.037
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.032
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.026
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.019
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.046
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.053
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.041
10.426
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claramente, vemos que cada request demorou cerca de 1 segundo, o que no total o tempo decorrido foi de &lt;strong&gt;10,4&lt;/strong&gt; segundos. Esta é a latência total para o caso de fazermos requisições sequenciais.&lt;/p&gt;

&lt;p&gt;E se fizermos &lt;strong&gt;requisições simultâneas&lt;/strong&gt;? Num cenário mais próximo do real, vamos supor que nossa aplicação web recebe 10 requisições no mesmo segundo em horários de pico.&lt;/p&gt;

&lt;p&gt;Para isto, conseguimos também utilizar o &lt;strong&gt;xargs&lt;/strong&gt; para simular, através da opção &lt;code&gt;-P&lt;/code&gt;, que representa a quantidade de processos simultâneos que o xargs irá utilizar para realizar os comandos. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Incrível! Com isto nosso web server atende 10 requisições simultâneas, fazendo com que o throughput total dos 10 requests fique em torno de 1 segundo, certo?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Calma, calabreso&lt;/em&gt;, vamos testar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;time echo&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;1..10&lt;span class="o"&gt;}&lt;/span&gt; | xargs &lt;span class="nt"&gt;-n1&lt;/span&gt; &lt;span class="nt"&gt;-P10&lt;/span&gt; bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"time curl localhost:3000"&lt;/span&gt;

&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.053
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;2.071
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;3.076
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;4.087
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;5.088
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;6.106
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;7.140
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;8.154
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;9.168
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;10.183
10.214
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Não melhorou nada!&lt;/strong&gt; Ter 10 requests simultâneos não quer dizer que nosso server consiga atender os 10 requests ao mesmo tempo. Muito pelo contrário, pode até piorar e prejudicar a latência total, pois há diversos requests na fila esperando para serem atendidos.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;o primeiro request demora 1 segundo&lt;/li&gt;
&lt;li&gt;o segundo request chega ao mesmo tempo mas demora 2 segundos&lt;/li&gt;
&lt;li&gt;o terceiro request chega ao mesmo tempo mas demora 3 segundos&lt;/li&gt;
&lt;li&gt;e assim sucessivamente...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nosso server é síncrono, e com isto podemos criar gargalos. Precisamos então que o server consiga lidar com &lt;strong&gt;concorrência&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Concorrência com forking de processos
&lt;/h2&gt;

&lt;p&gt;Uma das formas primitivas de concorrência e escalar um web server para atender mais de um request em simultâneo é com o uso de &lt;strong&gt;processos&lt;/strong&gt;. Como cada processo no sistema operacional tem sua &lt;em&gt;memória isolada&lt;/em&gt; dos demais, podemos fazer com que cada request seja atendido em um processo diferente.&lt;/p&gt;

&lt;p&gt;Para entender esta técnica, precisamos compreender que &lt;em&gt;todo programa de computador&lt;/em&gt; roda em um &lt;strong&gt;processo&lt;/strong&gt; no sistema operacional, e isto vimos bastante nos artigos anteriores. Dentro deste processo, o programa ainda roda em uma unidade de execução no SO chamada &lt;strong&gt;thread&lt;/strong&gt;. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Todo processo tem uma thread chamada &lt;em&gt;thread principal&lt;/em&gt;, que é onde está sendo executado o programa&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No exemplo anterior, quando chamamos o &lt;em&gt;sleep&lt;/em&gt;, a thread que está sendo suspensa por um tempo determinado é justamente a &lt;strong&gt;thread principal&lt;/strong&gt; do programa.&lt;/p&gt;

&lt;p&gt;A thread compartilha a memória do processo o qual ela faz parte, mas como precisamos criar &lt;strong&gt;outro processo&lt;/strong&gt;, temos de fazer um &lt;em&gt;forking&lt;/em&gt;, que basicamente &lt;em&gt;cria um processo filho copiando tudo&lt;/em&gt; o que o programa principal tem.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffhz3hnrjktfwv33zqdpv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffhz3hnrjktfwv33zqdpv.png" alt="forking de processos" width="800" height="666"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Repare que cada processo filho tem uma cópia do processo principal. O loop é basicamente o &lt;strong&gt;accept&lt;/strong&gt; do nosso web server, que fica em loop. Desta forma cada request pode ser atendido por um processo diferente, &lt;strong&gt;de forma concorrente&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Podemos fazer forking de processo com o uso da syscall &lt;em&gt;fork&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_fork&lt;/span&gt; &lt;span class="mi"&gt;57&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A rotina &lt;em&gt;handle&lt;/em&gt; mantém igual, com o sleep antes de escrever a resposta no socket:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;handle&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;lea&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;timespec&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_nanosleep&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;responseLen&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_close&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E na rotina &lt;strong&gt;accept&lt;/strong&gt;, adicionamos a chamada do fork logo após o request chegar no socket:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accept&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;struct&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;addrlen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_accept4&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;fork&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;processo&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_fork&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;se&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;retorno&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;fork&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;ZERO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;significa&lt;/span&gt; &lt;span class="nx"&gt;que&lt;/span&gt; &lt;span class="nx"&gt;est&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;sendo&lt;/span&gt; &lt;span class="nx"&gt;executado&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;partir&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;processo&lt;/span&gt; &lt;span class="nx"&gt;filho&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;Ent&lt;/span&gt;&lt;span class="err"&gt;ã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;rotina&lt;/span&gt; &lt;span class="s2"&gt;"handle"&lt;/span&gt; &lt;span class="err"&gt;é&lt;/span&gt; &lt;span class="nx"&gt;executada&lt;/span&gt;
    &lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;
    &lt;span class="nx"&gt;jz&lt;/span&gt; &lt;span class="nx"&gt;handle&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;quando&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;retorno&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="err"&gt;ã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="err"&gt;é&lt;/span&gt; &lt;span class="nx"&gt;ZERO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;significa&lt;/span&gt; &lt;span class="nx"&gt;que&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;execu&lt;/span&gt;&lt;span class="err"&gt;çã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;programa&lt;/span&gt; 
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;principal&lt;/span&gt; &lt;span class="nx"&gt;continuou&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;Ent&lt;/span&gt;&lt;span class="err"&gt;ã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;processo&lt;/span&gt; &lt;span class="nx"&gt;principal&lt;/span&gt; &lt;span class="nx"&gt;volta&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;loop&lt;/span&gt;
    &lt;span class="nx"&gt;jmp&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accept&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;depois de uma chamada ao &lt;strong&gt;fork&lt;/strong&gt;, a syscall retorna ZERO quando se está dentro do processo filho. Neste caso, a execução do processo filho continua com a rotina &lt;em&gt;handle&lt;/em&gt; e depois termina&lt;/li&gt;
&lt;li&gt;após a chamada do fork, se o retorno NÃO for ZERO, significa que a execução é do programa principal, então neste caso volta-se ao loop para esperar um novo request no socket&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ao executar com strace, podemos ver várias chamadas à syscall &lt;em&gt;fork&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;socket&lt;span class="o"&gt;(&lt;/span&gt;AF_INET, SOCK_STREAM, IPPROTO_IP&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 3
&lt;span class="nb"&gt;bind&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;3, &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;sa_family&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;AF_INET, &lt;span class="nv"&gt;sin_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;htons&lt;span class="o"&gt;(&lt;/span&gt;3000&lt;span class="o"&gt;)&lt;/span&gt;, &lt;span class="nv"&gt;sin_addr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;inet_addr&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"0.0.0.0"&lt;/span&gt;&lt;span class="o"&gt;)}&lt;/span&gt;, 16&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 0
listen&lt;span class="o"&gt;(&lt;/span&gt;3, 2&lt;span class="o"&gt;)&lt;/span&gt;                            &lt;span class="o"&gt;=&lt;/span&gt; 0
accept4&lt;span class="o"&gt;(&lt;/span&gt;3, NULL, NULL, 0&lt;span class="o"&gt;)&lt;/span&gt;               &lt;span class="o"&gt;=&lt;/span&gt; 4
fork&lt;span class="o"&gt;(&lt;/span&gt;strace: Process 12787 attached
&lt;span class="o"&gt;)&lt;/span&gt;                                  &lt;span class="o"&gt;=&lt;/span&gt; 12787
&lt;span class="o"&gt;[&lt;/span&gt;pid 12786] accept4&lt;span class="o"&gt;(&lt;/span&gt;3, NULL, NULL, 0 &amp;lt;unfinished ...&amp;gt;
&lt;span class="o"&gt;[&lt;/span&gt;pid 12787] nanosleep&lt;span class="o"&gt;({&lt;/span&gt;&lt;span class="nv"&gt;tv_sec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1, &lt;span class="nv"&gt;tv_nsec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0&lt;span class="o"&gt;}&lt;/span&gt;,  &amp;lt;unfinished ...&amp;gt;
&lt;span class="o"&gt;[&lt;/span&gt;pid 12786] &amp;lt;... accept4 resumed&amp;gt;&lt;span class="o"&gt;)&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; 5
&lt;span class="o"&gt;[&lt;/span&gt;pid 12786] fork&lt;span class="o"&gt;(&lt;/span&gt;strace: Process 12788 attached
&lt;span class="o"&gt;)&lt;/span&gt;                      &lt;span class="o"&gt;=&lt;/span&gt; 12788
&lt;span class="o"&gt;[&lt;/span&gt;pid 12788] nanosleep&lt;span class="o"&gt;({&lt;/span&gt;&lt;span class="nv"&gt;tv_sec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1, &lt;span class="nv"&gt;tv_nsec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0&lt;span class="o"&gt;}&lt;/span&gt;,  &amp;lt;unfinished ...&amp;gt;
&lt;span class="o"&gt;[&lt;/span&gt;pid 12786] accept4&lt;span class="o"&gt;(&lt;/span&gt;3, NULL, NULL, 0&lt;span class="o"&gt;)&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; 6
&lt;span class="o"&gt;[&lt;/span&gt;pid 12786] fork&lt;span class="o"&gt;(&lt;/span&gt;strace: Process 12789 attached
&lt;span class="o"&gt;)&lt;/span&gt;                      &lt;span class="o"&gt;=&lt;/span&gt; 12789
&lt;span class="o"&gt;[&lt;/span&gt;pid 12786] accept4&lt;span class="o"&gt;(&lt;/span&gt;3, NULL, NULL, 0&lt;span class="o"&gt;)&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; 7
&lt;span class="o"&gt;[&lt;/span&gt;pid 12786] fork&lt;span class="o"&gt;(&lt;/span&gt; &amp;lt;unfinished ...&amp;gt;
&lt;span class="o"&gt;[&lt;/span&gt;pid 12789] nanosleep&lt;span class="o"&gt;({&lt;/span&gt;&lt;span class="nv"&gt;tv_sec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1, &lt;span class="nv"&gt;tv_nsec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0&lt;span class="o"&gt;}&lt;/span&gt;, strace: Process 12790 attached
 &amp;lt;unfinished ...&amp;gt;
&lt;span class="o"&gt;[&lt;/span&gt;pid 12786] &amp;lt;... fork resumed&amp;gt;&lt;span class="o"&gt;)&lt;/span&gt;         &lt;span class="o"&gt;=&lt;/span&gt; 12790
&lt;span class="o"&gt;[&lt;/span&gt;pid 12790] nanosleep&lt;span class="o"&gt;({&lt;/span&gt;&lt;span class="nv"&gt;tv_sec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1, &lt;span class="nv"&gt;tv_nsec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0&lt;span class="o"&gt;}&lt;/span&gt;,  &amp;lt;unfinished ...&amp;gt;
&lt;span class="o"&gt;[&lt;/span&gt;pid 12786] accept4&lt;span class="o"&gt;(&lt;/span&gt;3, NULL, NULL, 0&lt;span class="o"&gt;)&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; 8
&lt;span class="o"&gt;[&lt;/span&gt;pid 12786] fork&lt;span class="o"&gt;(&lt;/span&gt;strace: Process 12791 attached
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E os tempos de resposta para 10 requests simultâneos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;time echo&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;1..10&lt;span class="o"&gt;}&lt;/span&gt; | xargs &lt;span class="nt"&gt;-n1&lt;/span&gt; &lt;span class="nt"&gt;-P10&lt;/span&gt; bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"time curl localhost:3000"&lt;/span&gt;

&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.049
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.051
1.053
1.052
1.055
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.051
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.052
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.056
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;2.106
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;2.116
2.138
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yay! Podemos ver que os requests são atendidos de forma concorrente, e que o tempo total ficou em &lt;strong&gt;2,1 segundos&lt;/strong&gt; para 10 requests simultâneos!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Lembrando que, quando estamos lidando com concorrência, não temos controle da ordem de execução dos processos, que são escalonados pelo sistema operacional. Esta preempção de processos pode fazer com que um request que chegou depois seja atendido primeiro. É uma das características de &lt;em&gt;race condition&lt;/em&gt; e é por isso que vemos os requests chegando fora de ordem.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Mas no nosso caso não importa. Cada request é único e não depende do anterior.&lt;/p&gt;




&lt;h2&gt;
  
  
  Concorrência com clone de processo
&lt;/h2&gt;

&lt;p&gt;Outra forma muito similar à chamada &lt;em&gt;fork&lt;/em&gt; é através da syscall &lt;strong&gt;clone&lt;/strong&gt;, que basicamente clona um processo, tal como fizemos no exemplo anterior, garantindo isolamento e concorrência.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_clone&lt;/span&gt; &lt;span class="mi"&gt;56&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E a diferença é que chamamos a syscall de clone, ao invés da syscall fork:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accept&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;struct&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;addrlen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_accept4&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;chamada&lt;/span&gt; &lt;span class="err"&gt;à&lt;/span&gt; &lt;span class="nx"&gt;syscall&lt;/span&gt; &lt;span class="nx"&gt;clone&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;com&lt;/span&gt; &lt;span class="nx"&gt;argumentos&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;ZERO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;significa&lt;/span&gt; &lt;span class="nx"&gt;que&lt;/span&gt; &lt;span class="nx"&gt;ser&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;feito&lt;/span&gt; &lt;span class="nx"&gt;um&lt;/span&gt; &lt;span class="nx"&gt;clone&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;processo&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_clone&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;se&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;retorno&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;zero&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;execu&lt;/span&gt;&lt;span class="err"&gt;çã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="err"&gt;é&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;partir&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;processo&lt;/span&gt; &lt;span class="nx"&gt;filho&lt;/span&gt;
    &lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;
    &lt;span class="nx"&gt;jz&lt;/span&gt; &lt;span class="nx"&gt;handle&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;continua&lt;/span&gt;&lt;span class="err"&gt;çã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;execu&lt;/span&gt;&lt;span class="err"&gt;çã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;processo&lt;/span&gt; &lt;span class="nx"&gt;principal&lt;/span&gt;
    &lt;span class="nx"&gt;jmp&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accept&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;depois de uma chamada ao &lt;strong&gt;clone&lt;/strong&gt;, a syscall retorna ZERO quando se está dentro do processo filho. Neste caso, a execução do processo filho continua com a rotina &lt;em&gt;handle&lt;/em&gt; e depois termina&lt;/li&gt;
&lt;li&gt;após a chamada do clone, se o retorno NÃO for ZERO, significa que a execução é do programa principal, então neste caso volta-se ao loop para esperar um novo request no socket&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Executamos com strace e:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.062
1.064
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.063
1.061
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.071
1.061
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.059
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.069
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;2.135
2.128
2.148
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ainda servindo 10 requests simultâneos &lt;strong&gt;perto dos 2 segundos&lt;/strong&gt;! &lt;em&gt;Not bad&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Entretanto, forking ou clone de processos leva a um &lt;strong&gt;gasto excessivo de memória&lt;/strong&gt;, pois cada processo filho é exatamente uma cópia do processo principal. Se o principal tem 200MB de memória, com 4 forks teríamos um gasto total de 800MB de memória.&lt;/p&gt;

&lt;p&gt;Chegou o momento de falarmos das &lt;strong&gt;threads&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Concorrência com threads
&lt;/h2&gt;

&lt;p&gt;Vamos relembrar o que falamos no início do artigo:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Todo processo tem uma thread chamada &lt;em&gt;thread principal&lt;/em&gt;, que é onde está sendo executado o programa&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Apesar de todo programa rodar dentro de uma thread, podemos também criar mais threads que &lt;strong&gt;compartilham a memória do mesmo processo&lt;/strong&gt;, e para isto podemos fazer uso da mesma syscall &lt;strong&gt;clone&lt;/strong&gt;, mas passando argumentos diferentes que tornam este clone uma &lt;em&gt;thread dentro do mesmo processo&lt;/em&gt;, e não uma cópia inteira do processo.&lt;/p&gt;

&lt;p&gt;Desta forma, ficamos sempre com UM processo mas atendendo requests em threads diferentes, &lt;strong&gt;gastando assim menos memória&lt;/strong&gt; se comparado com forking de processos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvszydp3du1ntg72xizmd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvszydp3du1ntg72xizmd.png" alt="threads" width="614" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Entendendo a criação de uma thread
&lt;/h3&gt;

&lt;p&gt;Antes de adaptarmos o código do server para utilizar threads, vamos dar um passo atrás e entender como se cria uma thread em Assembly.&lt;/p&gt;

&lt;p&gt;Para criar uma thread, fazemos uso da syscall &lt;strong&gt;clone&lt;/strong&gt;. De acordo com a &lt;a href="https://man7.org/linux/man-pages/man2/clone.2.html" rel="noopener noreferrer"&gt;documentação&lt;/a&gt;, a syscall clone cria um processo "filho", similar ao que fizemos no fork. Mas a diferença é que a syscall clone permite um maior controle sobre o que será compartilhado entre o processo principal e o processo filho.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_clone&lt;/span&gt; &lt;span class="mi"&gt;56&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Coisas que podem ser compartilhadas (ou não):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;espaço de endereço de memória virtual&lt;/li&gt;
&lt;li&gt;tabela de descritores de arquivos&lt;/li&gt;
&lt;li&gt;tabela de handlers de sinais&lt;/li&gt;
&lt;li&gt;entre outros recursos...&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;No exemplo anterior utilizamos a syscall clone passando argumentos a ZERO, o que significa que não queríamos compartilhar nada entre os processos, portanto uma cópia seria feita como no forking de processos&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Para a execução da syscall, precisamos enviar 2 argumentos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;rdi&lt;/strong&gt;: representa as &lt;em&gt;flags&lt;/em&gt;, que modificam o comportamento do que será compartilhado com o processo filho (thread)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;rsi&lt;/strong&gt;: ponteiro para a função que a thread irá executar, que precisa ser definido dentro de uma &lt;strong&gt;área reservada na memória&lt;/strong&gt;, ou seja, precisamos alocar um novo bloco de memória para a thread poder colocar a função e seus argumentos&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Portanto, para criar uma thread, precisamos de &lt;strong&gt;thread flags&lt;/strong&gt; e &lt;strong&gt;alocação de memória&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Thread flags
&lt;/h3&gt;

&lt;p&gt;Em RDI, vamos passar as seguintes flags:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CLONE_VM&lt;/strong&gt;: processo principal e processo filho compartilham o mesmo espaço de memória virtual&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CLONE_FS&lt;/strong&gt;: processos compartilham o mesmo sistema de arquivos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CLONE_FILES&lt;/strong&gt;: processos compartilham a mesma tabela de descritor de arquivos (file descriptor table)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CLONE_SIGHAND&lt;/strong&gt;: processos compartilham a mesma tabela de handlers de sinais (signal handlers)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CLONE_PARENT&lt;/strong&gt;: processos compartilham o mesmo parent, ou seja, o processo "filho" na verdade é filho do processo parent do processo original (mesmo porque estamos falando de uma thread que compartilha o mesmo processo)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CLONE_THREAD&lt;/strong&gt;: o processo filho é colocado no mesmo grupo de threads do processo original&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CLONE_IO&lt;/strong&gt;: processos compartilham o mesmo contexto de I/O&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;No fim das contas, estamos criando um processo "filho" mas que compartilha recursos com o processo principal. &lt;strong&gt;Este é o princípio da thread.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CLONE_VM&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;CLONE_FS&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;CLONE_FILES&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;CLONE_SIGHAND&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;CLONE_PARENT&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;CLONE_THREAD&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;CLONE_IO&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Alocação de memória com brk
&lt;/h3&gt;

&lt;p&gt;Em RSI, precisamos indicar o ponteiro para a função na memória, neste caso o ponteiro da rotina &lt;strong&gt;handle&lt;/strong&gt;, que tem a lógica de imprimir a mensagem  e etc. Mas aqui não basta indicar o ponteiro, mas sim em &lt;strong&gt;que região da memória&lt;/strong&gt; do processo a thread irá armazenar a função, seus argumentos e variáveis locais.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Cada thread precisa ter sua própria região na memória para armazenar a função e argumentos. É como se a thread tivesse uma área de "stack" só dela&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Para alocar memória, vamos relembrar como funciona o layout de um programa na memória:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fco0lxnlhbx2nz7uhx4k6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fco0lxnlhbx2nz7uhx4k6.png" alt="layout de memória" width="580" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nos endereços de memória mais baixos, temos o programa, e a seguir temos os &lt;em&gt;dados estáticos&lt;/em&gt; (data). No topo, que é onde ficam os endereços mais altos, temos a &lt;em&gt;stack&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;E no meio, o que temos &lt;strong&gt;a seguir a seção de dados&lt;/strong&gt; é uma área enorme disponível na memória. A syscall &lt;strong&gt;brk&lt;/strong&gt; permite mudar o ponto onde &lt;em&gt;termina a seção de dados&lt;/em&gt;, também chamado de &lt;strong&gt;program break&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Podemos ficar mudando este break em direção aos endereços mais altos. Por exemplo, se chamarmos a syscall brk passando argumento ZERO, ela devolve o endereço de memória do program break, que é onde termina a seção de dados:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;

&lt;span class="p"&gt;...&lt;/span&gt;

&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt;
&lt;span class="nx"&gt;syscall&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O que temos em RAX é &lt;code&gt;0x403000&lt;/code&gt;, que é exatamente o endereço de memória onde termina a seção de dados. Vamos modificar o break &lt;strong&gt;andando UM byte pra frente&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;
&lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt;
&lt;span class="nx"&gt;syscall&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora, RAX traz o endereço do novo program break, que é &lt;code&gt;0x403001&lt;/code&gt;. Ou seja, agora podemos manipular este endereço de memória no nosso programa.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd32sk2d6w5eitngvri0y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd32sk2d6w5eitngvri0y.png" alt="program break" width="564" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;E o quê isto tem a ver com a thread? &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Podemos alocar &lt;strong&gt;uma quantidade arbitrária de bytes&lt;/strong&gt; para a thread utilizar nesta área na memória. Como o break é sempre modificado, a próxima thread irá utilizar outra área de memória, e assim sucessivamente!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbir1ll5slqqmsmhu7q25.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbir1ll5slqqmsmhu7q25.png" alt="criação de threads" width="439" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Um "Hello, world" com threads em Assembly
&lt;/h3&gt;

&lt;p&gt;Vamos escrever um exemplo simples antes de ir para o web server. Primeiro, definimos as constantes, dentre elas as syscalls e as flags pra criação de threads:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;global&lt;/span&gt; &lt;span class="nx"&gt;_start&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_clone&lt;/span&gt; &lt;span class="mi"&gt;56&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;        
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CHILD_STACK_SIZE&lt;/span&gt; &lt;span class="mi"&gt;4096&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CLONE_VM&lt;/span&gt; &lt;span class="mh"&gt;0x00000100&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CLONE_FS&lt;/span&gt; &lt;span class="mh"&gt;0x00000200&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CLONE_FILES&lt;/span&gt; &lt;span class="mh"&gt;0x00000400&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CLONE_PARENT&lt;/span&gt; &lt;span class="mh"&gt;0x00008000&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CLONE_THREAD&lt;/span&gt; &lt;span class="mh"&gt;0x00010000&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CLONE_IO&lt;/span&gt; &lt;span class="mh"&gt;0x80000000&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CLONE_SIGHAND&lt;/span&gt; &lt;span class="mh"&gt;0x00000800&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A seguir, na seção de dados, temos a mensagem "Hello, world" que a thread irá imprimir:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"Hello"&lt;/span&gt;
&lt;span class="nl"&gt;msgLen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;equ&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Na seção &lt;em&gt;text&lt;/em&gt;, o entrypoint do programa faz uma chamada à rotina da &lt;em&gt;thread&lt;/em&gt; e a seguir termina:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;
&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="nx"&gt;thread&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora, a definição da rotina &lt;code&gt;handle&lt;/code&gt; que a thread irá executar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;handle&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;msgLen&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;A thread imprime a mensagem no STDOUT e termina. Sim, a thread precisa terminar, caso contrário o sistema emite um segmentation fault&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;E por fim, vamos detalhar o processo da rotina da &lt;em&gt;thread&lt;/em&gt; (explicação nos comentários do exemplo a seguir):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;thread&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Busca&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="nx"&gt;atual&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="nx"&gt;guarda&lt;/span&gt; &lt;span class="nx"&gt;em&lt;/span&gt; &lt;span class="nx"&gt;RDX&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;Na&lt;/span&gt; &lt;span class="nx"&gt;primeira&lt;/span&gt; &lt;span class="nx"&gt;vez&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;valor&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="err"&gt;é&lt;/span&gt; &lt;span class="mh"&gt;0x403000&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Modifica&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="nx"&gt;atual&lt;/span&gt; &lt;span class="nx"&gt;andando&lt;/span&gt; &lt;span class="mi"&gt;4096&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt; &lt;span class="err"&gt;à&lt;/span&gt; &lt;span class="nx"&gt;frente&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Ap&lt;/span&gt;&lt;span class="err"&gt;ó&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="nx"&gt;esta&lt;/span&gt; &lt;span class="nx"&gt;chamada&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="nx"&gt;passa&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;ser&lt;/span&gt; &lt;span class="mh"&gt;0x404000&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;
    &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CHILD_STACK_SIZE&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;Thread&lt;/span&gt; &lt;span class="nx"&gt;flags&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;como&lt;/span&gt; &lt;span class="nx"&gt;deve&lt;/span&gt; &lt;span class="nx"&gt;ser&lt;/span&gt; &lt;span class="nx"&gt;feito&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;compartilhamento&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;recursos&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;entre&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;processo&lt;/span&gt; &lt;span class="nx"&gt;principal&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;processo&lt;/span&gt; &lt;span class="nx"&gt;filho&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CLONE_VM&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;CLONE_FS&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;CLONE_FILES&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;CLONE_SIGHAND&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;CLONE_PARENT&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;CLONE_THREAD&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;CLONE_IO&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;Endere&lt;/span&gt;&lt;span class="err"&gt;ç&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;mem&lt;/span&gt;&lt;span class="err"&gt;ó&lt;/span&gt;&lt;span class="nx"&gt;ria&lt;/span&gt; &lt;span class="nx"&gt;em&lt;/span&gt; &lt;span class="nx"&gt;RSI&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;é&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="nx"&gt;atual&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;4096&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Retiramos&lt;/span&gt; &lt;span class="nx"&gt;tamb&lt;/span&gt;&lt;span class="err"&gt;é&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;caber&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;ponteiro&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;fun&lt;/span&gt;&lt;span class="err"&gt;çã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;
    &lt;span class="nx"&gt;lea&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rdx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;CHILD_STACK_SIZE&lt;/span&gt; &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;No&lt;/span&gt; &lt;span class="nx"&gt;endere&lt;/span&gt;&lt;span class="err"&gt;ç&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;em&lt;/span&gt; &lt;span class="nx"&gt;RSI&lt;/span&gt; &lt;span class="nx"&gt;colocamos&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;ponteiro&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;fun&lt;/span&gt;&lt;span class="err"&gt;çã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="s2"&gt;"handle"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Como&lt;/span&gt; &lt;span class="nx"&gt;endere&lt;/span&gt;&lt;span class="err"&gt;ç&lt;/span&gt;&lt;span class="nx"&gt;amento&lt;/span&gt; &lt;span class="nx"&gt;em&lt;/span&gt; &lt;span class="nx"&gt;x86_64&lt;/span&gt; &lt;span class="err"&gt;é&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;é&lt;/span&gt; &lt;span class="nx"&gt;por&lt;/span&gt; &lt;span class="nx"&gt;isto&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;que&lt;/span&gt; &lt;span class="nx"&gt;no&lt;/span&gt; &lt;span class="nx"&gt;passo&lt;/span&gt; &lt;span class="nx"&gt;anterior&lt;/span&gt; &lt;span class="nx"&gt;fizemos&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rdx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;4096&lt;/span&gt; &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;qword&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;handle&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_clone&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E pronto, ao executar o programa, temos a mensagem "Hello" na saída do programa que foi feita pela thread.&lt;/p&gt;

&lt;p&gt;Caso o programa principal faça &lt;code&gt;call thread&lt;/code&gt; 2 vezes, a próxima thread irá ter em RSI o break modificado, iniciando em &lt;code&gt;0x404000&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Modificando o server para suportar multi-threading
&lt;/h3&gt;

&lt;p&gt;Agora vamos trazer o código necessário para modificar o server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_clone&lt;/span&gt; &lt;span class="mi"&gt;56&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thread flags:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CHILD_STACK_SIZE&lt;/span&gt; &lt;span class="mi"&gt;4096&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CLONE_VM&lt;/span&gt; &lt;span class="mh"&gt;0x00000100&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CLONE_FS&lt;/span&gt; &lt;span class="mh"&gt;0x00000200&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CLONE_FILES&lt;/span&gt; &lt;span class="mh"&gt;0x00000400&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CLONE_PARENT&lt;/span&gt; &lt;span class="mh"&gt;0x00008000&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CLONE_THREAD&lt;/span&gt; &lt;span class="mh"&gt;0x00010000&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CLONE_IO&lt;/span&gt; &lt;span class="mh"&gt;0x80000000&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CLONE_SIGHAND&lt;/span&gt; &lt;span class="mh"&gt;0x00000800&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rotina &lt;em&gt;accept&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accept&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;struct&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;addrlen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_accept4&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Chamada&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;Ir&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;ser&lt;/span&gt; &lt;span class="nx"&gt;executada&lt;/span&gt; &lt;span class="nx"&gt;assincronamente&lt;/span&gt; &lt;span class="nx"&gt;tal&lt;/span&gt; &lt;span class="nx"&gt;como&lt;/span&gt; &lt;span class="nx"&gt;no&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;forking&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;processos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mas&lt;/span&gt; &lt;span class="nx"&gt;compartilhando&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;mem&lt;/span&gt;&lt;span class="err"&gt;ó&lt;/span&gt;&lt;span class="nx"&gt;ria&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;processo&lt;/span&gt; &lt;span class="nx"&gt;principal&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="nx"&gt;thread&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Processo&lt;/span&gt; &lt;span class="nx"&gt;principal&lt;/span&gt; &lt;span class="nx"&gt;volta&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;loop&lt;/span&gt;
    &lt;span class="nx"&gt;jmp&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accept&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Definição da &lt;em&gt;thread&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;thread&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;
    &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CHILD_STACK_SIZE&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CLONE_VM&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;CLONE_FS&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;CLONE_FILES&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;CLONE_SIGHAND&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;CLONE_PARENT&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;CLONE_THREAD&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;CLONE_IO&lt;/span&gt;
    &lt;span class="nx"&gt;lea&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rdx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;CHILD_STACK_SIZE&lt;/span&gt; &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;qword&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;handle&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_clone&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Aqui seguimos o mesmo padrão do exemplo anterior: aloca memória com brk e a seguir executa a syscall clone com as flags de compartilhamento de recursos&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;E a lógica da rotina &lt;em&gt;handle&lt;/em&gt; &lt;strong&gt;que será executada pela thread&lt;/strong&gt;, que faz o &lt;em&gt;sleep&lt;/em&gt;, a seguir escreve no socket a mensagem, fecha o socket da requisição e por fim termina sua execução:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;handle&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;lea&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;timespec&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_nanosleep&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;responseLen&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_close&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com 1 chamada isolada, temos o seguinte output com strace:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;socket&lt;span class="o"&gt;(&lt;/span&gt;AF_INET, SOCK_STREAM, IPPROTO_IP&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 3
&lt;span class="nb"&gt;bind&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;3, &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;sa_family&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;AF_INET, &lt;span class="nv"&gt;sin_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;htons&lt;span class="o"&gt;(&lt;/span&gt;3000&lt;span class="o"&gt;)&lt;/span&gt;, &lt;span class="nv"&gt;sin_addr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;inet_addr&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"0.0.0.0"&lt;/span&gt;&lt;span class="o"&gt;)}&lt;/span&gt;, 16&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 0
listen&lt;span class="o"&gt;(&lt;/span&gt;3, 2&lt;span class="o"&gt;)&lt;/span&gt;                            &lt;span class="o"&gt;=&lt;/span&gt; 0
accept4&lt;span class="o"&gt;(&lt;/span&gt;3, NULL, NULL, 0&lt;span class="o"&gt;)&lt;/span&gt;               &lt;span class="o"&gt;=&lt;/span&gt; 4
brk&lt;span class="o"&gt;(&lt;/span&gt;NULL&lt;span class="o"&gt;)&lt;/span&gt;                               &lt;span class="o"&gt;=&lt;/span&gt; 0x9da000
brk&lt;span class="o"&gt;(&lt;/span&gt;0x9db000&lt;span class="o"&gt;)&lt;/span&gt;                           &lt;span class="o"&gt;=&lt;/span&gt; 0x9db000
clone&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;child_stack&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0x9daff8, &lt;span class="nv"&gt;flags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_PARENT|CLONE_THREAD|CLONE_IOstrace: Process 13078 attached
&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 13078
&lt;span class="o"&gt;[&lt;/span&gt;pid 13078] nanosleep&lt;span class="o"&gt;({&lt;/span&gt;&lt;span class="nv"&gt;tv_sec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1, &lt;span class="nv"&gt;tv_nsec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0&lt;span class="o"&gt;}&lt;/span&gt;,  &amp;lt;unfinished ...&amp;gt;
&lt;span class="o"&gt;[&lt;/span&gt;pid 13077] accept4&lt;span class="o"&gt;(&lt;/span&gt;3, NULL, NULL, 0 &amp;lt;unfinished ...&amp;gt;
&lt;span class="o"&gt;[&lt;/span&gt;pid 13078] &amp;lt;... nanosleep resumed&amp;gt;0x9daff8&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 0
&lt;span class="o"&gt;[&lt;/span&gt;pid 13078] write&lt;span class="o"&gt;(&lt;/span&gt;4, &lt;span class="s2"&gt;"HTTP/1.1 200 OK&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s2"&gt;Content-Type: t"&lt;/span&gt;..., 86&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 86
&lt;span class="o"&gt;[&lt;/span&gt;pid 13078] close&lt;span class="o"&gt;(&lt;/span&gt;4&lt;span class="o"&gt;)&lt;/span&gt;                    &lt;span class="o"&gt;=&lt;/span&gt; 0
&lt;span class="o"&gt;[&lt;/span&gt;pid 13078] &lt;span class="nb"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;0&lt;span class="o"&gt;)&lt;/span&gt;                     &lt;span class="o"&gt;=&lt;/span&gt; ?
&lt;span class="o"&gt;[&lt;/span&gt;pid 13078] +++ exited with 0 +++
&amp;lt;... accept4 resumed&amp;gt;&lt;span class="o"&gt;)&lt;/span&gt;                  &lt;span class="o"&gt;=&lt;/span&gt; ? ERESTARTSYS &lt;span class="o"&gt;(&lt;/span&gt;To be restarted &lt;span class="k"&gt;if &lt;/span&gt;SA_RESTART is &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nt"&gt;---&lt;/span&gt; SIGWINCH &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;si_signo&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;SIGWINCH, &lt;span class="nv"&gt;si_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;SI_KERNEL&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;---&lt;/span&gt;
accept4&lt;span class="o"&gt;(&lt;/span&gt;3, NULL, NULL, 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vamos reparar na sequência de chamadas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;depois do accept, foi feita uma chamada a &lt;strong&gt;brk&lt;/strong&gt; modificando o program break (alocando memória)&lt;/li&gt;
&lt;li&gt;a seguir, vemos a chamada &lt;strong&gt;clone&lt;/strong&gt;, que acoplou o processo filho 13078&lt;/li&gt;
&lt;li&gt;a thread (13078) é suspensa com &lt;strong&gt;nanosleep&lt;/strong&gt; por 1 segundo&lt;/li&gt;
&lt;li&gt;o processo principal (13077) volta para o &lt;strong&gt;accept&lt;/strong&gt; e fica a espera de mais requests&lt;/li&gt;
&lt;li&gt;a thread &lt;strong&gt;escreve&lt;/strong&gt; no socket&lt;/li&gt;
&lt;li&gt;a thread &lt;strong&gt;fecha&lt;/strong&gt; o socket&lt;/li&gt;
&lt;li&gt;a thread é encerrada com &lt;strong&gt;exit&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Agora, simulando os 10 requests simultâneos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.060
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.064
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.064
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.062
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.068
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.073
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;2.098
2.094
2.097
2.091
2.113
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Superb!&lt;/em&gt; Temos o mesmo tempo total de &lt;strong&gt;2,1 segundos&lt;/strong&gt; mas gastando &lt;strong&gt;muito menos memória&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;Entretanto, temos um pequeno problema. Imagina que num momento de grande número de acessos, a nossa aplicação recebe 1000 requests concorrentes. E se receber 5000? Ou então &lt;strong&gt;dezenas de milhares&lt;/strong&gt; de requests simultâneos?&lt;/p&gt;

&lt;p&gt;Uma &lt;strong&gt;chamada de sistema tem custo&lt;/strong&gt;. O sistema operacional oferece um limite de threads que podem ser criadas ao mesmo tempo por processo. Se deixarmos assim, nossa aplicação corre um grande risco de ultrapassar esse limite, além de que chamadas a &lt;em&gt;brk + clone&lt;/em&gt; têm seus custos de criação.&lt;/p&gt;

&lt;p&gt;E se pudéssemos reciclar um número limitado de threads? Sim, estamos falando de &lt;strong&gt;pool de threads&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Concorrência com thread pool
&lt;/h2&gt;

&lt;p&gt;A forma mais comum de trabalhar com thread é com &lt;em&gt;thread pool&lt;/em&gt;. Basicamente, definimos um número arbitrário de threads &lt;strong&gt;que nunca terminam&lt;/strong&gt;, mas ficam em loop consumindo mensagens de alguma estrutura de dados. Esta estrutura pode ser uma &lt;strong&gt;fila&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi8ysvzs13lo7jju7opfs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi8ysvzs13lo7jju7opfs.png" alt="thread pool" width="405" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Uma thread em loop
&lt;/h3&gt;

&lt;p&gt;Vamos inicialmente definir que teremos apenas UMA thread em loop lendo mensagens da fila. O processo deverá ser o seguinte:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;processo principal inicia uma thread&lt;/li&gt;
&lt;li&gt;a thread fica em loop lendo mensagens (socket) da fila. Quando tiver vazia, repete o loop. Quando houver algum socket na fila, a thread executa a lógica que é fazer o &lt;em&gt;nanosleep&lt;/em&gt;, escrever no socket, fechar o socket, e voltar para o loop de leitura da fila&lt;/li&gt;
&lt;li&gt;processo principal continua execução após criação da thread, onde fica em loop lendo requisições que chegam no socket (accept). Quando uma requisição chega, adiciona o socket na fila e volta para o loop do &lt;strong&gt;accept&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vamos passo a passo, começando pelas constantes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;global&lt;/span&gt; &lt;span class="nx"&gt;_start&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_socket&lt;/span&gt; &lt;span class="mi"&gt;41&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_bind&lt;/span&gt; &lt;span class="mi"&gt;49&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_listen&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_accept4&lt;/span&gt; &lt;span class="mi"&gt;288&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_close&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_nanosleep&lt;/span&gt; &lt;span class="mi"&gt;35&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_clone&lt;/span&gt; &lt;span class="mi"&gt;56&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;AF_INET&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SOCK_STREAM&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SOCK_PROTOCOL&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;BACKLOG&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CR&lt;/span&gt; &lt;span class="mh"&gt;0xD&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;LF&lt;/span&gt; &lt;span class="mh"&gt;0xA&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CHILD_STACK_SIZE&lt;/span&gt; &lt;span class="mi"&gt;4096&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CLONE_VM&lt;/span&gt; &lt;span class="mh"&gt;0x00000100&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CLONE_FS&lt;/span&gt; &lt;span class="mh"&gt;0x00000200&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CLONE_FILES&lt;/span&gt; &lt;span class="mh"&gt;0x00000400&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CLONE_PARENT&lt;/span&gt; &lt;span class="mh"&gt;0x00008000&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CLONE_THREAD&lt;/span&gt; &lt;span class="mh"&gt;0x00010000&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CLONE_IO&lt;/span&gt; &lt;span class="mh"&gt;0x80000000&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CLONE_SIGHAND&lt;/span&gt; &lt;span class="mh"&gt;0x00000800&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A seguir, a seção de dados:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;sockaddr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nl"&gt;sa_family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dw&lt;/span&gt; &lt;span class="nx"&gt;AF_INET&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt;
    &lt;span class="nl"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dw&lt;/span&gt; &lt;span class="mh"&gt;0xB80B&lt;/span&gt;         &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt;
    &lt;span class="nl"&gt;ip_addr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dd&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;           &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt;
    &lt;span class="nl"&gt;sin_zero&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dq&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;          &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt;
&lt;span class="nl"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
    &lt;span class="nl"&gt;headline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"HTTP/1.1 200 OK"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;LF&lt;/span&gt;
    &lt;span class="nl"&gt;content_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: text/html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;LF&lt;/span&gt;
    &lt;span class="nl"&gt;content_length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"Content-Length: 22"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;LF&lt;/span&gt;
    &lt;span class="nl"&gt;crlf&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="nx"&gt;CR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;LF&lt;/span&gt;
    &lt;span class="nl"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;"&lt;/span&gt;
&lt;span class="nl"&gt;responseLen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;equ&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;
&lt;span class="nl"&gt;timespec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nl"&gt;tv_sec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dq&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="nl"&gt;tv_nsec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dq&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="nl"&gt;queuePtr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bss&lt;/span&gt;
&lt;span class="nl"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;resb&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;
&lt;span class="nl"&gt;queue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;resb&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Repare que a fila representa 8 bytes fixos (para nosso exemplo é o suficiente), utilizando também um ponteiro para manipular a fila. &lt;/p&gt;

&lt;p&gt;Seguindo com o código, o programa inicia logo disparando a thread:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;
&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="nx"&gt;thread&lt;/span&gt;        
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A seguir vêm as rotinas habituais (vou omitir pra poupar caracteres neste artigo): &lt;em&gt;socket, bind e listen&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;O &lt;strong&gt;accept&lt;/strong&gt; fica da seguinte forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accept&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;struct&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;addrlen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_accept4&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="nx"&gt;enqueue&lt;/span&gt;

    &lt;span class="nx"&gt;jmp&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accept&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Okay, agora, ao invés de &lt;em&gt;chamar uma thread&lt;/em&gt;, o programa principal enfileira o socket da requisição. Lógica do &lt;code&gt;enqueue&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;enqueue&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;xor&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;dl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;queuePtr&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;queue&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;   
    &lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;queuePtr&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui, estamos manipulando o ponteiro em &lt;code&gt;queue&lt;/code&gt; utilizando &lt;code&gt;queuePtr&lt;/code&gt;, incrementando um byte quando algo é adicionado na fila.&lt;/p&gt;

&lt;p&gt;Agora vamos à implementação da rotina da thread:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;thread&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;
    &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CHILD_STACK_SIZE&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_brk&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CLONE_VM&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;CLONE_FS&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;CLONE_FILES&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;CLONE_SIGHAND&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;CLONE_PARENT&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;CLONE_THREAD&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;CLONE_IO&lt;/span&gt;
    &lt;span class="nx"&gt;lea&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rdx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;CHILD_STACK_SIZE&lt;/span&gt; &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;qword&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;handle&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_clone&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nada de novo por enquanto. O que modifica é a rotina &lt;em&gt;handle&lt;/em&gt; (explicação detalhada nos comentários):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;handle&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Verifica&lt;/span&gt; &lt;span class="nx"&gt;se&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;fila&lt;/span&gt; &lt;span class="nx"&gt;est&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;vazia&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;Se&lt;/span&gt; &lt;span class="nx"&gt;estiver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fica&lt;/span&gt; &lt;span class="nx"&gt;em&lt;/span&gt; &lt;span class="nx"&gt;loop&lt;/span&gt; &lt;span class="nx"&gt;infinito&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Repare&lt;/span&gt; &lt;span class="nx"&gt;que&lt;/span&gt; &lt;span class="nx"&gt;este&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="err"&gt;ó&lt;/span&gt;&lt;span class="nx"&gt;digo&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="err"&gt;ã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;est&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;otimizado&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;Loop&lt;/span&gt; &lt;span class="nx"&gt;infinito&lt;/span&gt; 
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;acarreta&lt;/span&gt; &lt;span class="nx"&gt;alto&lt;/span&gt; &lt;span class="nx"&gt;consumo&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;CPU&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;Nas&lt;/span&gt; &lt;span class="nx"&gt;pr&lt;/span&gt;&lt;span class="err"&gt;ó&lt;/span&gt;&lt;span class="nx"&gt;ximas&lt;/span&gt; &lt;span class="nx"&gt;se&lt;/span&gt;&lt;span class="err"&gt;çõ&lt;/span&gt;&lt;span class="nx"&gt;es&lt;/span&gt; &lt;span class="nx"&gt;vamos&lt;/span&gt; &lt;span class="nx"&gt;resolver&lt;/span&gt; &lt;span class="nx"&gt;isto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Por&lt;/span&gt; &lt;span class="nx"&gt;ora&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;vamos&lt;/span&gt; &lt;span class="nx"&gt;aceitar&lt;/span&gt; &lt;span class="nx"&gt;este&lt;/span&gt; &lt;span class="nx"&gt;consumo&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;CPU&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
    &lt;span class="nx"&gt;cmp&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;queuePtr&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;je&lt;/span&gt; &lt;span class="nx"&gt;handle&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Remove&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;faz&lt;/span&gt; &lt;span class="nx"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;fila&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="nx"&gt;guarda&lt;/span&gt; &lt;span class="nx"&gt;em&lt;/span&gt; &lt;span class="nx"&gt;R8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="nx"&gt;dequeue&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Processo&lt;/span&gt; &lt;span class="nx"&gt;normal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;faz&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;nanosleep&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="nx"&gt;segundo&lt;/span&gt; &lt;span class="nx"&gt;simulando&lt;/span&gt; &lt;span class="nx"&gt;lat&lt;/span&gt;&lt;span class="err"&gt;ê&lt;/span&gt;&lt;span class="nx"&gt;ncia&lt;/span&gt;
    &lt;span class="nx"&gt;lea&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;timespec&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_nanosleep&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Escreve&lt;/span&gt; &lt;span class="nx"&gt;no&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt; &lt;span class="nx"&gt;que&lt;/span&gt; &lt;span class="nx"&gt;est&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;em&lt;/span&gt; &lt;span class="nx"&gt;R8&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;responseLen&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Fecha&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_close&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Volta&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="err"&gt;í&lt;/span&gt;&lt;span class="nx"&gt;cio&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;jmp&lt;/span&gt; &lt;span class="nx"&gt;handle&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E por último, a lógica da rotina &lt;em&gt;dequeue&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;dequeue&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;xor&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;
    &lt;span class="nx"&gt;xor&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;al&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;queue&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rcx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;loop_dequeue&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;cmp&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;queuePtr&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;je&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;return_dequeue&lt;/span&gt;

    &lt;span class="nx"&gt;cmp&lt;/span&gt; &lt;span class="nx"&gt;cl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;queuePtr&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;je&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done_dequeue&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;shift&lt;/span&gt;
    &lt;span class="nx"&gt;xor&lt;/span&gt; &lt;span class="nx"&gt;r10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;r10&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r10b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;queue&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;rcx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;queue&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;rcx&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;r10b&lt;/span&gt;

    &lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;rcx&lt;/span&gt;
    &lt;span class="nx"&gt;jmp&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;loop_dequeue&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done_dequeue&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;dec&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;queuePtr&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;return_dequeue&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Por enquanto não vou entrar em detalhes em como trabalhar com filas em Assembly. Vou deixar estes detalhes para outro artigo, que irá tratar especificamente de arrays, filas e listas ligadas. Em breve!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pronto, já podemos executar o server e...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.042
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;2.059
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;3.071
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;4.083
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;5.090
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;6.094
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;7.112
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;8.121
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;9.140
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;10.150
10.166
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Ouch!&lt;/em&gt; Voltamos aos 10 segundos. Mas isto se deve ao fato de termos apenas &lt;em&gt;uma thread&lt;/em&gt; em loop. Vamos aumentar o número de threads na pool.&lt;/p&gt;

&lt;h3&gt;
  
  
  5 threads em loop
&lt;/h3&gt;

&lt;p&gt;A seguir modificamos o programa para inicializar 5 threads, para que desta forma nosso server tenha mais capacidade em atender requests simultâneos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;
&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;initialize_pool&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pool&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="nx"&gt;thread&lt;/span&gt;        
    &lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;
    &lt;span class="nx"&gt;cmp&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
    &lt;span class="nx"&gt;je&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;socket&lt;/span&gt;
    &lt;span class="nx"&gt;jmp&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pool&lt;/span&gt;
&lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="p"&gt;....&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com este loop fazemos &lt;code&gt;call thread&lt;/code&gt; 5 vezes, pelo que cada thread, e ainda utilizando o exemplo anterior, irá ficar em loop buscando mensagens na fila.&lt;/p&gt;

&lt;p&gt;Executamos o código com 1 request e temos sucesso:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;time &lt;/span&gt;curl localhost:3000

&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.022
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mas no output do strace, após a resposta, vemos uma sequência de erros das threads:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;[pid 13483] write&lt;span class="o"&gt;(&lt;/span&gt;4, &lt;span class="s2"&gt;"HTTP/1.1 200 OK&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s2"&gt;Content-Type: t"&lt;/span&gt;..., 86 &amp;lt;unfinished ...&amp;gt;
&lt;span class="o"&gt;[&lt;/span&gt;pid 13482] write&lt;span class="o"&gt;(&lt;/span&gt;0, &lt;span class="s2"&gt;"HTTP/1.1 200 OK&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s2"&gt;Content-Type: t"&lt;/span&gt;..., 86 &amp;lt;unfinished ...&amp;gt;
&lt;span class="o"&gt;[&lt;/span&gt;pid 13480] write&lt;span class="o"&gt;(&lt;/span&gt;0, &lt;span class="s2"&gt;"HTTP/1.1 200 OK&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s2"&gt;Content-Type: t"&lt;/span&gt;..., 86 &amp;lt;unfinished ...&amp;gt;
&lt;span class="o"&gt;[&lt;/span&gt;pid 13484] &amp;lt;... write resumed&amp;gt;&lt;span class="o"&gt;)&lt;/span&gt;        &lt;span class="o"&gt;=&lt;/span&gt; 86
&lt;span class="o"&gt;[&lt;/span&gt;pid 13481] write&lt;span class="o"&gt;(&lt;/span&gt;4, &lt;span class="s2"&gt;"HTTP/1.1 200 OK&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s2"&gt;Content-Type: t"&lt;/span&gt;..., 86HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 22

&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt; &amp;lt;unfinished ...&amp;gt;
&lt;span class="o"&gt;[&lt;/span&gt;pid 13480] &amp;lt;... write resumed&amp;gt;&lt;span class="o"&gt;)&lt;/span&gt;        &lt;span class="o"&gt;=&lt;/span&gt; 86
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 22

&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;[pid 13484] close&lt;span class="o"&gt;(&lt;/span&gt;0 &amp;lt;unfinished ...&amp;gt;
&lt;span class="o"&gt;[&lt;/span&gt;pid 13483] &amp;lt;... write resumed&amp;gt;&lt;span class="o"&gt;)&lt;/span&gt;        &lt;span class="o"&gt;=&lt;/span&gt; 86
&lt;span class="o"&gt;[&lt;/span&gt;pid 13482] &amp;lt;... write resumed&amp;gt;&lt;span class="o"&gt;)&lt;/span&gt;        &lt;span class="o"&gt;=&lt;/span&gt; 86
&lt;span class="o"&gt;[&lt;/span&gt;pid 13480] close&lt;span class="o"&gt;(&lt;/span&gt;0 &amp;lt;unfinished ...&amp;gt;
&lt;span class="o"&gt;[&lt;/span&gt;pid 13484] &amp;lt;... close resumed&amp;gt;&lt;span class="o"&gt;)&lt;/span&gt;        &lt;span class="o"&gt;=&lt;/span&gt; 0
&lt;span class="o"&gt;[&lt;/span&gt;pid 13481] &amp;lt;... write resumed&amp;gt;&lt;span class="o"&gt;)&lt;/span&gt;        &lt;span class="o"&gt;=&lt;/span&gt; 86
&lt;span class="o"&gt;[&lt;/span&gt;pid 13484] nanosleep&lt;span class="o"&gt;({&lt;/span&gt;&lt;span class="nv"&gt;tv_sec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1, &lt;span class="nv"&gt;tv_nsec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0&lt;span class="o"&gt;}&lt;/span&gt;,  &amp;lt;unfinished ...&amp;gt;
&lt;span class="o"&gt;[&lt;/span&gt;pid 13483] close&lt;span class="o"&gt;(&lt;/span&gt;4 &amp;lt;unfinished ...&amp;gt;
&lt;span class="o"&gt;[&lt;/span&gt;pid 13482] close&lt;span class="o"&gt;(&lt;/span&gt;0 &amp;lt;unfinished ...&amp;gt;
&lt;span class="o"&gt;[&lt;/span&gt;pid 13481] close&lt;span class="o"&gt;(&lt;/span&gt;4 &amp;lt;unfinished ...&amp;gt;
&lt;span class="o"&gt;[&lt;/span&gt;pid 13480] &amp;lt;... close resumed&amp;gt;&lt;span class="o"&gt;)&lt;/span&gt;        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt; EBADF &lt;span class="o"&gt;(&lt;/span&gt;Bad file descriptor&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;pid 13483] &amp;lt;... close resumed&amp;gt;&lt;span class="o"&gt;)&lt;/span&gt;        &lt;span class="o"&gt;=&lt;/span&gt; 0
&lt;span class="o"&gt;[&lt;/span&gt;pid 13482] &amp;lt;... close resumed&amp;gt;&lt;span class="o"&gt;)&lt;/span&gt;        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt; EBADF &lt;span class="o"&gt;(&lt;/span&gt;Bad file descriptor&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;pid 13481] &amp;lt;... close resumed&amp;gt;&lt;span class="o"&gt;)&lt;/span&gt;        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt; EBADF &lt;span class="o"&gt;(&lt;/span&gt;Bad file descriptor&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A thread tentou fechar o socket descriptor da requisição mas outra thread tentou ler o socket de forma concorrente (Bad file descriptor). &lt;/p&gt;

&lt;p&gt;Quando envolve &lt;strong&gt;mais de uma thread&lt;/strong&gt; consumindo o mesmo recurso (neste caso a fila), precisamos de um mecanismo de &lt;strong&gt;sincronização&lt;/strong&gt;, que no caso são &lt;em&gt;locks&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sincronização com futex
&lt;/h3&gt;

&lt;p&gt;Com &lt;em&gt;locks&lt;/em&gt;, conseguimos controlar o acesso a um recurso compartilhado &lt;em&gt;entre diferentes threads&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Através da syscall &lt;strong&gt;futex&lt;/strong&gt;, podemos suspender uma thread baseando-se em uma "variável condicional". De forma oposta, podemos &lt;em&gt;tornar uma thread de volta à execução&lt;/em&gt; baseando-se também na variável condicional.&lt;/p&gt;

&lt;p&gt;Esta técnica de &lt;em&gt;variável condicional&lt;/em&gt; (condvar) é um primitivo de sincronização bastante utilizado. No nosso caso para controle da fila, queremos o seguinte cenário:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a thread verifica se há algo na fila. Caso a fila esteja vazia, a thread é suspensa com &lt;em&gt;futex wait&lt;/em&gt; através de uma variável condicional&lt;/li&gt;
&lt;li&gt;quando algo for adicionado na fila, outra thread/processo "emite um sinal" chamando a syscall &lt;em&gt;futex wake&lt;/em&gt; na mesma variável condicional. &lt;/li&gt;
&lt;li&gt;quando o sinal é emitido, neste momento a thread que tem o acesso ao lock (variável condicional) é trazida de volta ao contexto, então lê a mensagem da fila e executa a ação necessária. Após, se a fila estiver vazia, repete o processo com &lt;em&gt;futex wait&lt;/em&gt; e fica novamente suspensa&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Desta forma, garantimos que as threads não ficam consumindo a CPU em loop indefinidamente&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Modificando o código, começamos por definir a syscall:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_futex&lt;/span&gt; &lt;span class="mi"&gt;202&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A seguir, na seção de dados &lt;code&gt;.bss&lt;/code&gt; declaramos a &lt;em&gt;variável condicional&lt;/em&gt; ocupando 8 bytes, que será utilizada como sincronização do futex:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bss&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="nl"&gt;condvar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;resb&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Na rotina &lt;code&gt;enqueue&lt;/code&gt;, &lt;em&gt;emitimos o sinal&lt;/em&gt; após o socket ser adicionado na fila:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;enqueue&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;xor&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;dl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;queuePtr&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;queue&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;   
    &lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;queuePtr&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="nx"&gt;emit_signal&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A lógica o &lt;em&gt;emit_signal&lt;/em&gt; (explicação nos comentários):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;emit_signal&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Endere&lt;/span&gt;&lt;span class="err"&gt;ç&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;mem&lt;/span&gt;&lt;span class="err"&gt;ó&lt;/span&gt;&lt;span class="nx"&gt;ria&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;vari&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt;&lt;span class="nx"&gt;vel&lt;/span&gt; &lt;span class="nx"&gt;condicional&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;condvar&lt;/span&gt;

   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Flags&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;Futex&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;WAKE&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;que&lt;/span&gt; &lt;span class="nx"&gt;ir&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;trazer&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;thread&lt;/span&gt;
   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;volta&lt;/span&gt; &lt;span class="nx"&gt;ao&lt;/span&gt; &lt;span class="nx"&gt;contexto&lt;/span&gt;
   &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;FUTEX_WAKE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;FUTEX_PRIVATE_FLAG&lt;/span&gt; 

   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Argumentos&lt;/span&gt; &lt;span class="nx"&gt;adicionais&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;que&lt;/span&gt; &lt;span class="nx"&gt;neste&lt;/span&gt; &lt;span class="nx"&gt;caso&lt;/span&gt; &lt;span class="nx"&gt;vamos&lt;/span&gt; &lt;span class="nx"&gt;deixar&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;ZERO&lt;/span&gt;
   &lt;span class="nx"&gt;xor&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;
   &lt;span class="nx"&gt;xor&lt;/span&gt; &lt;span class="nx"&gt;r10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;r10&lt;/span&gt;
   &lt;span class="nx"&gt;xor&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;

   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Chamada&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;syscall&lt;/span&gt;
   &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_futex&lt;/span&gt;
   &lt;span class="nx"&gt;syscall&lt;/span&gt;
   &lt;span class="nx"&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora, modificamos a rotina &lt;em&gt;handle&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;handle&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; 
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Caso&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;fila&lt;/span&gt; &lt;span class="nx"&gt;esteja&lt;/span&gt; &lt;span class="nx"&gt;vazia&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fazemos&lt;/span&gt; &lt;span class="nx"&gt;jump&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="s2"&gt;"wait"&lt;/span&gt;
    &lt;span class="nx"&gt;cmp&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;queuePtr&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;         
    &lt;span class="nx"&gt;je&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wait&lt;/span&gt;           

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Faz&lt;/span&gt; &lt;span class="nx"&gt;pop&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;fila&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="nx"&gt;segue&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;fluxo&lt;/span&gt; &lt;span class="nx"&gt;normal&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="nx"&gt;dequeue&lt;/span&gt;      
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;

    &lt;span class="nx"&gt;lea&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;timespec&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_nanosleep&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;r10&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;responseLen&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;r10&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_close&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Volta&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="err"&gt;í&lt;/span&gt;&lt;span class="nx"&gt;cio&lt;/span&gt;
    &lt;span class="nx"&gt;jmp&lt;/span&gt; &lt;span class="nx"&gt;handle&lt;/span&gt;       
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wait&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Chamada&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;wait_condvar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;que&lt;/span&gt; &lt;span class="nx"&gt;vai&lt;/span&gt; &lt;span class="nx"&gt;suspender&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;thread&lt;/span&gt; &lt;span class="nx"&gt;atual&lt;/span&gt; &lt;span class="nx"&gt;com&lt;/span&gt; &lt;span class="nx"&gt;FUTEX&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="nx"&gt;wait_condvar&lt;/span&gt; 
    &lt;span class="nx"&gt;jmp&lt;/span&gt; &lt;span class="nx"&gt;handle&lt;/span&gt;       
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E, por último e não menos importante, a lógica da rotina &lt;em&gt;wait_condvar&lt;/em&gt;, que suspende a thread de execução:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;wait_condvar&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Endere&lt;/span&gt;&lt;span class="err"&gt;ç&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;mem&lt;/span&gt;&lt;span class="err"&gt;ó&lt;/span&gt;&lt;span class="nx"&gt;ria&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;vari&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt;&lt;span class="nx"&gt;vel&lt;/span&gt; &lt;span class="nx"&gt;condicional&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;condvar&lt;/span&gt;   

   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Flags&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;Futex&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;WAIT&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;que&lt;/span&gt; &lt;span class="nx"&gt;ir&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;suspender&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;thread&lt;/span&gt;
   &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;FUTEX_WAIT&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;FUTEX_PRIVATE_FLAG&lt;/span&gt; 
   &lt;span class="nx"&gt;xor&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;
   &lt;span class="nx"&gt;xor&lt;/span&gt; &lt;span class="nx"&gt;r10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;r10&lt;/span&gt;              
   &lt;span class="nx"&gt;xor&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;               
   &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_futex&lt;/span&gt;
   &lt;span class="nx"&gt;syscall&lt;/span&gt;
   &lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;
   &lt;span class="nx"&gt;jz&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done_condvar&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done_condvar&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
   &lt;span class="nx"&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assim que iniciamos o server com &lt;em&gt;strace&lt;/em&gt;, podemos ver as syscalls em ação:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brk&lt;span class="o"&gt;(&lt;/span&gt;NULL&lt;span class="o"&gt;)&lt;/span&gt;                               &lt;span class="o"&gt;=&lt;/span&gt; 0x155c000
brk&lt;span class="o"&gt;(&lt;/span&gt;0x155d000&lt;span class="o"&gt;)&lt;/span&gt;                          &lt;span class="o"&gt;=&lt;/span&gt; 0x155d000
clone&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;child_stack&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0x155cff8, &lt;span class="nv"&gt;flags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_PARENT|CLONE_THREAD|CLONE_IOstrace: Process 13539 attached
&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 13539
&lt;span class="o"&gt;[&lt;/span&gt;pid 13539] futex&lt;span class="o"&gt;(&lt;/span&gt;0x402088, FUTEX_WAIT_PRIVATE, 0, NULL &amp;lt;unfinished ...&amp;gt;
&lt;span class="o"&gt;[&lt;/span&gt;pid 13538] brk&lt;span class="o"&gt;(&lt;/span&gt;NULL&lt;span class="o"&gt;)&lt;/span&gt;                   &lt;span class="o"&gt;=&lt;/span&gt; 0x155d000
&lt;span class="o"&gt;[&lt;/span&gt;pid 13538] brk&lt;span class="o"&gt;(&lt;/span&gt;0x155e000&lt;span class="o"&gt;)&lt;/span&gt;              &lt;span class="o"&gt;=&lt;/span&gt; 0x155e000
&lt;span class="o"&gt;[&lt;/span&gt;pid 13538] clone&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;child_stack&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0x155dff8, &lt;span class="nv"&gt;flags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_PARENT|CLONE_THREAD|CLONE_IOstrace: Process 13540 attached
&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 13540
&lt;span class="o"&gt;[&lt;/span&gt;pid 13540] futex&lt;span class="o"&gt;(&lt;/span&gt;0x402088, FUTEX_WAIT_PRIVATE, 0, NULL &amp;lt;unfinished ...&amp;gt;
&lt;span class="o"&gt;[&lt;/span&gt;pid 13538] brk&lt;span class="o"&gt;(&lt;/span&gt;NULL&lt;span class="o"&gt;)&lt;/span&gt;                   &lt;span class="o"&gt;=&lt;/span&gt; 0x155e000
&lt;span class="o"&gt;[&lt;/span&gt;pid 13538] brk&lt;span class="o"&gt;(&lt;/span&gt;0x155f000&lt;span class="o"&gt;)&lt;/span&gt;              &lt;span class="o"&gt;=&lt;/span&gt; 0x155f000
&lt;span class="o"&gt;[&lt;/span&gt;pid 13538] clone&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;child_stack&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0x155eff8, &lt;span class="nv"&gt;flags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_PARENT|CLONE_THREAD|CLONE_IOstrace: Process 13541 attached
&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 13541
&lt;span class="o"&gt;[&lt;/span&gt;pid 13541] futex&lt;span class="o"&gt;(&lt;/span&gt;0x402088, FUTEX_WAIT_PRIVATE, 0, NULL &amp;lt;unfinished ...&amp;gt;
&lt;span class="o"&gt;[&lt;/span&gt;pid 13538] brk&lt;span class="o"&gt;(&lt;/span&gt;NULL&lt;span class="o"&gt;)&lt;/span&gt;                   &lt;span class="o"&gt;=&lt;/span&gt; 0x155f000
&lt;span class="o"&gt;[&lt;/span&gt;pid 13538] brk&lt;span class="o"&gt;(&lt;/span&gt;0x1560000&lt;span class="o"&gt;)&lt;/span&gt;              &lt;span class="o"&gt;=&lt;/span&gt; 0x1560000
&lt;span class="o"&gt;[&lt;/span&gt;pid 13538] clone&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;child_stack&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0x155fff8, &lt;span class="nv"&gt;flags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_PARENT|CLONE_THREAD|CLONE_IOstrace: Process 13542 attached
&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 13542
&lt;span class="o"&gt;[&lt;/span&gt;pid 13542] futex&lt;span class="o"&gt;(&lt;/span&gt;0x402088, FUTEX_WAIT_PRIVATE, 0, NULL &amp;lt;unfinished ...&amp;gt;
&lt;span class="o"&gt;[&lt;/span&gt;pid 13538] brk&lt;span class="o"&gt;(&lt;/span&gt;NULL&lt;span class="o"&gt;)&lt;/span&gt;                   &lt;span class="o"&gt;=&lt;/span&gt; 0x1560000
&lt;span class="o"&gt;[&lt;/span&gt;pid 13538] brk&lt;span class="o"&gt;(&lt;/span&gt;0x1561000&lt;span class="o"&gt;)&lt;/span&gt;              &lt;span class="o"&gt;=&lt;/span&gt; 0x1561000
&lt;span class="o"&gt;[&lt;/span&gt;pid 13538] clone&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;child_stack&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0x1560ff8, &lt;span class="nv"&gt;flags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_PARENT|CLONE_THREAD|CLONE_IOstrace: Process 13543 attached
&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 13543
&lt;span class="o"&gt;[&lt;/span&gt;pid 13538] socket&lt;span class="o"&gt;(&lt;/span&gt;AF_INET, SOCK_STREAM, IPPROTO_IP &amp;lt;unfinished ...&amp;gt;
&lt;span class="o"&gt;[&lt;/span&gt;pid 13543] futex&lt;span class="o"&gt;(&lt;/span&gt;0x402088, FUTEX_WAIT_PRIVATE, 0, NULL &amp;lt;unfinished ...&amp;gt;
&lt;span class="o"&gt;[&lt;/span&gt;pid 13538] &amp;lt;... socket resumed&amp;gt;&lt;span class="o"&gt;)&lt;/span&gt;       &lt;span class="o"&gt;=&lt;/span&gt; 3
&lt;span class="o"&gt;[&lt;/span&gt;pid 13538] &lt;span class="nb"&gt;bind&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;3, &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;sa_family&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;AF_INET, &lt;span class="nv"&gt;sin_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;htons&lt;span class="o"&gt;(&lt;/span&gt;3000&lt;span class="o"&gt;)&lt;/span&gt;, &lt;span class="nv"&gt;sin_addr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;inet_addr&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"0.0.0.0"&lt;/span&gt;&lt;span class="o"&gt;)}&lt;/span&gt;, 16&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 0
&lt;span class="o"&gt;[&lt;/span&gt;pid 13538] listen&lt;span class="o"&gt;(&lt;/span&gt;3, 2&lt;span class="o"&gt;)&lt;/span&gt;                &lt;span class="o"&gt;=&lt;/span&gt; 0
&lt;span class="o"&gt;[&lt;/span&gt;pid 13538] accept4&lt;span class="o"&gt;(&lt;/span&gt;3, NULL, NULL, 0&lt;span class="o"&gt;)&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; ? ERESTARTSYS &lt;span class="o"&gt;(&lt;/span&gt;To be restarted &lt;span class="k"&gt;if &lt;/span&gt;SA_RESTART is &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;pid 13538] &lt;span class="nt"&gt;---&lt;/span&gt; SIGWINCH &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;si_signo&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;SIGWINCH, &lt;span class="nv"&gt;si_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;SI_KERNEL&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;---&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;pid 13538] accept4&lt;span class="o"&gt;(&lt;/span&gt;3, NULL, NULL, 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Repare que cada thread faz a chamada a futex com &lt;em&gt;FUTEX WAIT&lt;/em&gt;, e isto vemos acontecer 5 vezes no trace. Ou seja, as 5 threads estão suspensas &lt;strong&gt;sem consumir CPU&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Ao fazer o primeiro request, temos o seguinte resultado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;)&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; 4
&lt;span class="o"&gt;[&lt;/span&gt;pid 13538] futex&lt;span class="o"&gt;(&lt;/span&gt;0x402088, FUTEX_WAKE_PRIVATE, 0&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 1
&lt;span class="o"&gt;[&lt;/span&gt;pid 13539] &amp;lt;... futex resumed&amp;gt;&lt;span class="o"&gt;)&lt;/span&gt;        &lt;span class="o"&gt;=&lt;/span&gt; 0
&lt;span class="o"&gt;[&lt;/span&gt;pid 13538] accept4&lt;span class="o"&gt;(&lt;/span&gt;3, NULL, NULL, 0 &amp;lt;unfinished ...&amp;gt;
&lt;span class="o"&gt;[&lt;/span&gt;pid 13539] nanosleep&lt;span class="o"&gt;({&lt;/span&gt;&lt;span class="nv"&gt;tv_sec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1, &lt;span class="nv"&gt;tv_nsec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0&lt;span class="o"&gt;}&lt;/span&gt;, NULL&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 0
&lt;span class="o"&gt;[&lt;/span&gt;pid 13539] write&lt;span class="o"&gt;(&lt;/span&gt;4, &lt;span class="s2"&gt;"HTTP/1.1 200 OK&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s2"&gt;Content-Type: t"&lt;/span&gt;..., 86&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 86
&lt;span class="o"&gt;[&lt;/span&gt;pid 13539] close&lt;span class="o"&gt;(&lt;/span&gt;4&lt;span class="o"&gt;)&lt;/span&gt;                    &lt;span class="o"&gt;=&lt;/span&gt; 0
&lt;span class="o"&gt;[&lt;/span&gt;pid 13539] futex&lt;span class="o"&gt;(&lt;/span&gt;0x402088, FUTEX_WAIT_PRIVATE, 0, NULL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;o processo principal recebeu a mensagem no socket, enfileirou e executou &lt;em&gt;futex&lt;/em&gt; com &lt;strong&gt;FUTEX_WAKE&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;uma das threads foi trazida de volta ao contexto e fez a sua devida execução (nanosleep + write + close)&lt;/li&gt;
&lt;li&gt;o processo principal voltou para o accept a espera de mais requests no socket&lt;/li&gt;
&lt;li&gt;a thread terminou seu trabalho, viu que não tinha mais nada na fila e executou &lt;em&gt;futex&lt;/em&gt; com &lt;strong&gt;FUTEX_WAIT&lt;/strong&gt;, ficando novamente suspensa&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finalmente, podemos executar 10 requests simultâneos e...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.079
1.082
1.083
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;1.062
1.083
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;2.087
2.088
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;2.100
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;2.101
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;2.110
2.127
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Nice!&lt;/em&gt; Com uma pool de 5 threads, conseguimos atingir &lt;strong&gt;2,1 segundos&lt;/strong&gt; para 10 requests concorrentes. Agora temos concorrência consumindo muito menos recursos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;menos memória, pois não é forking de processos&lt;/li&gt;
&lt;li&gt;menos CPU, pois as threads não ficam em loop infinito&lt;/li&gt;
&lt;li&gt;menos latência, pois com uma limitação de 5 threads, novos requests não criam novas threads&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Alocação de memória com mmap
&lt;/h2&gt;

&lt;p&gt;Um problema comum ao utilizar &lt;em&gt;brk&lt;/em&gt; é que a memória pode ficar fragmentada. Uma vez que o program break foi modificado, aquela memória pode ser utilizada, mas torna muito difícil ser reciclada. &lt;/p&gt;

&lt;p&gt;Uma forma de lidar com este problema de fragmentação é utilizar uma syscall que trata de reservar uma área na memória que pode ser reciclada futuramente. Estamos falando da syscall &lt;strong&gt;mmap&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;thread&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CHILD_STACK_SIZE&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PROT_WRITE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;PROT_READ&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;MAP_ANONYMOUS&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;MAP_PRIVATE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;MAP_GROWSDOWN&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_mmap&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CLONE_VM&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;CLONE_FS&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;CLONE_FILES&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;CLONE_SIGHAND&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;CLONE_PARENT&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;CLONE_THREAD&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;CLONE_IO&lt;/span&gt;
    &lt;span class="nx"&gt;lea&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rax&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;CHILD_STACK_SIZE&lt;/span&gt; &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;qword&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;handle&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_clone&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ao invés de chamar &lt;em&gt;brk&lt;/em&gt;, podemos chamar &lt;strong&gt;mmap&lt;/strong&gt;, especificando:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;rdi&lt;/strong&gt;: endereço de memória onde deve ser mapeado. Se tiver ZERO, o sistema operacional se encarrega de trazer um endereço de memória disponível&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;rsi&lt;/strong&gt;: tamanho do espaço reservado na memória. No nosso caso, queremos 4096 bytes para a thread&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;rdx&lt;/strong&gt;: proteção de memória, neste caso queremos que a memória possa ser tanto escrita (PROT_WRITE) quanto lida (PROT_READ) pela thread&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;r10&lt;/strong&gt;: flags de mapeamento

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MAP_ANONYMOUS&lt;/strong&gt;: o mapeamento não é associado a nenhum arquivo ou descritor de arquivo (modo anônimo)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MAP_PRIVATE&lt;/strong&gt;: mapeamento privado com &lt;em&gt;copy-on-write&lt;/em&gt;, ou seja, os dados serão copiados à medida em que são escritos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MAP_GROWSDOWN&lt;/strong&gt;: o mapeamento é usado no formato "stack", ou seja, o mapeamento é dos endereços maiores em direção aos menores&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Com &lt;em&gt;mmap&lt;/em&gt;, podemos fazer uso da sua contrapartida, a syscall &lt;strong&gt;unmmap&lt;/strong&gt;, que permite reciclar uma determinada área na memória que não é mais utilizada, evitando fragmentação.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Esta técnica é muito utilizada pela libc através da função &lt;strong&gt;malloc&lt;/strong&gt;. Com mmap podemos definir uma memória heap para nosso programa&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;É isto, na prática não terá nenhum efeito com relação ao exemplo anterior. Mas esta seção foi apenas para trazer uma forma diferente de alocar memória para a thread.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Ufa! Finalmente chegamos ao final da saga. Passamos por uma &lt;a href="https://dev.to/leandronsp/construindo-um-web-server-em-assembly-x86-parte-i-introducao-14p5"&gt;introdução&lt;/a&gt;, onde a seguir fizemos uma abordagem pela &lt;a href="https://dev.to/leandronsp/construindo-um-web-server-em-assembly-x86-parte-ii-historia-e-arquitetura-2jb9"&gt;história e arquitetura de computadores&lt;/a&gt;, para então analisar &lt;a href="https://dev.to/leandronsp/construindo-um-web-server-em-assembly-x86-parte-iii-codigo-de-maquina-bgk"&gt;código de máquina&lt;/a&gt;, que foi a base para entrar em &lt;a href="https://dev.to/leandronsp/construindo-um-web-server-em-assembly-x86-parte-iv-um-assembly-modesto-oif"&gt;assembly x86&lt;/a&gt; de fato, para finalmente &lt;a href="https://dev.to/leandronsp/construindo-um-web-server-em-assembly-x86-parte-v-finalmente-o-server-9e5"&gt;concluir o desenvolvimento do web server&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Este último artigo foi uma abordagem para multi-threading em Assembly, passando por conceitos de concorrência como &lt;em&gt;forking de processos&lt;/em&gt;, &lt;strong&gt;clone&lt;/strong&gt;, threading, pool de threads e sincronização com locks.&lt;/p&gt;

&lt;p&gt;Declaro aqui então o fim da &lt;strong&gt;saga desenvolvendo um web server em Assembly x86&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Até a próxima saga!&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;p&gt;&lt;br&gt;
Synchronization: mutexes and condition variables&lt;br&gt;
&lt;a href="https://cs61.seas.harvard.edu/site/2018/Synch3/" rel="noopener noreferrer"&gt;https://cs61.seas.harvard.edu/site/2018/Synch3/&lt;/a&gt;&lt;br&gt;
Synchronization, atomics and mutexes&lt;br&gt;
&lt;a href="https://cs.brown.edu/courses/csci0300/2023/notes/l22.html" rel="noopener noreferrer"&gt;https://cs.brown.edu/courses/csci0300/2023/notes/l22.html&lt;/a&gt;&lt;br&gt;
Basics of Futexes&lt;br&gt;
&lt;a href="https://eli.thegreenplace.net/2018/basics-of-futexes/" rel="noopener noreferrer"&gt;https://eli.thegreenplace.net/2018/basics-of-futexes/&lt;/a&gt;&lt;br&gt;
Raw Linux threads via syscalls&lt;br&gt;
&lt;a href="https://nullprogram.com/blog/2015/05/15/" rel="noopener noreferrer"&gt;https://nullprogram.com/blog/2015/05/15/&lt;/a&gt;&lt;br&gt;
Condition variables with Futex&lt;br&gt;
&lt;a href="https://www.remlab.net/op/futex-condvar.shtml" rel="noopener noreferrer"&gt;https://www.remlab.net/op/futex-condvar.shtml&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>assembly</category>
    </item>
    <item>
      <title>Construindo um web server em Assembly x86, parte V, finalmente o server</title>
      <dc:creator>Leandro Proença</dc:creator>
      <pubDate>Sat, 25 May 2024 00:14:20 +0000</pubDate>
      <link>https://dev.to/leandronsp/construindo-um-web-server-em-assembly-x86-parte-v-finalmente-o-server-9e5</link>
      <guid>https://dev.to/leandronsp/construindo-um-web-server-em-assembly-x86-parte-v-finalmente-o-server-9e5</guid>
      <description>&lt;p&gt;No &lt;a href="https://dev.to/leandronsp/construindo-um-web-server-em-assembly-x86-parte-iv-um-assembly-modesto-oif"&gt;artigo anterior&lt;/a&gt;, passamos pelos fundamentos de Assembly, onde foi possível entender alguns conceitos básicos tais como tipos de registradores, &lt;strong&gt;stack&lt;/strong&gt;, loops, FLAGS etc, tudo sendo feito com debugging via &lt;em&gt;GDB&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Agora, vamos de fato construir um web server muito simples que devolve um HTML com a frase "Hello, World". A meta é chegarmos nisto:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6745f6h98cph2u50aa8x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6745f6h98cph2u50aa8x.png" alt="hello world"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O processo para chegarmos a este objetivo consiste em cobrir fundamentos de Web, passando por sockets, TCP e HTTP, enquanto vamos explorando conceitos práticos em Assembly x86.&lt;/p&gt;




&lt;h2&gt;
  
  
  Agenda
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
Arquitetura Web

&lt;ul&gt;
&lt;li&gt;Cliente-servidor&lt;/li&gt;
&lt;li&gt;Modelo OSI&lt;/li&gt;
&lt;li&gt;Sockets e TCP&lt;/li&gt;
&lt;li&gt;HTTP&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Como funciona um servidor web

&lt;ul&gt;
&lt;li&gt;4 syscalls para o resgate&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Um server modesto em Assembly

&lt;ul&gt;
&lt;li&gt;Criando o socket&lt;/li&gt;
&lt;li&gt;Fazendo bind no socket&lt;/li&gt;
&lt;li&gt;Preparando para receber conexões&lt;/li&gt;
&lt;li&gt;Chegou o momento de aceitar clientes&lt;/li&gt;
&lt;li&gt;Resposta do servidor e fechamento da conexão&lt;/li&gt;
&lt;li&gt;Mas o servidor deve ficar em loop, não?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Conclusão&lt;/li&gt;

&lt;li&gt;Referências&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  Arquitetura Web
&lt;/h2&gt;

&lt;p&gt;Para criar um servidor web, precisamos manipular &lt;em&gt;mensagens HTTP&lt;/em&gt;, que são transportadas via camada de transporte TCP/IP através de uma rede.&lt;/p&gt;

&lt;p&gt;Estas mensagens são enviadas entre diferentes dispositivos conectados a uma rede, que pode ser privada (local) ou pública. Regularmente, comunicação HTTP é feita entre 2 dispositivos, sendo um deles o &lt;em&gt;cliente&lt;/em&gt; e outro o &lt;em&gt;servidor&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Vamos brevemente falar de cada um destes conceitos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cliente-servidor
&lt;/h3&gt;

&lt;p&gt;Numa arquitetura cliente-servidor, temos 2 dispositivos conectados a uma rede de computadores:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz9io56i8xzadm9cqvepe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz9io56i8xzadm9cqvepe.png" alt="cliente servidor"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para um servidor web, é necessário que o cliente realize uma &lt;strong&gt;conexão&lt;/strong&gt; com o servidor, em seguida faça uma &lt;strong&gt;requisição&lt;/strong&gt;, pelo que o servidor deve devolver uma &lt;strong&gt;resposta&lt;/strong&gt; e, por último, &lt;strong&gt;fechar a conexão&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmaxau6kx9t18u6r049r0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmaxau6kx9t18u6r049r0.png" alt="connect request response"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mas como esta mensagem deve ser enviada? Quem garante a entrega? E caso ocorra falha de sinal na camada física (cabeamento de rede), como assegurar que cada "pacote" da mensagem seja entregue em ordem?&lt;/p&gt;

&lt;p&gt;É pra isto que foi criado o &lt;strong&gt;modelo de comunicação OSI&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Modelo OSI
&lt;/h3&gt;

&lt;p&gt;OSI é um modelo de referência para comunicação entre diferentes dispositivos através de diferentes redes, que estabelece um conjunto de camadas que vai desde a camada física até a camada de formato de mensagens.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsdfapddkf7j5uzojvgzg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsdfapddkf7j5uzojvgzg.png" alt="modelo OSI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Camada física&lt;/strong&gt;: responsável pelo tráfego de informações através de meios físicos, tais como bluetooth, frequência de rádio, cabos etc&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Camada de enlace de rede&lt;/strong&gt;: responsável pela decodificação e codificação de mensagens em frames, do meio físico para o meio digital e vice-versa&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Camada de rede&lt;/strong&gt;: é aqui que definimos protocolos de rede, tais como o &lt;em&gt;protocolo de internet&lt;/em&gt;, também conhecido como &lt;strong&gt;IP&lt;/strong&gt; (Internet Protocol)&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Na web, os dados trafegam geralmente através de uma rede de computadores pública, global e descentralizada, neste caso a Internet&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Camada de transporte&lt;/strong&gt;: camada responsável por características de entrega, tais como definir critérios de confiabilidade e ordem dos pacotes de mensagens. Por exemplo, nesta camada temos o &lt;em&gt;protocolo de  controle de transmissão&lt;/em&gt;, ou &lt;strong&gt;TCP&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Camada de sessão e apresentação&lt;/strong&gt;: aqui vão critérios de informações que podem ser vinculadas a uma determinada conexão entre diferentes dispositivos, bem como o formato de apresentação das informações na rede&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Camada de aplicação&lt;/strong&gt;: nesta camada, temos a definição do formato de mensagens em um nível mais "aplicacional", como por exemplo protocolo HTTP (Hypertext Transfer Protocol), FTP, SSH entre outros&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Entretanto fica aqui uma questão: como que todo esse modelo de comunicação em rede se converte em algo prático num programa dentro de um sistema operacional?&lt;/p&gt;

&lt;p&gt;Chegou o momento de falar sobre &lt;em&gt;sockets&lt;/em&gt; e TCP.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sockets e TCP
&lt;/h3&gt;

&lt;p&gt;Num computador, todos os programas são encapsulados dentro de uma estrutura chamada &lt;em&gt;processo&lt;/em&gt;, como vimos em artigos anteriores.&lt;/p&gt;

&lt;p&gt;Quando falamos em cliente na aquitetura cliente-servidor, estamos falando de um processo rodando dentro de um computador, e o mesmo vale para o servidor, onde cada processo tem seu próprio identificador, ou &lt;em&gt;PID&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7q9yi7cdbs42p0352s24.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7q9yi7cdbs42p0352s24.png" alt="pids"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sabendo que processos são isolados, foram definidas diferentes formas de comunicação entre processos (também conhecido como IPC, ou &lt;em&gt;inter process communication&lt;/em&gt;), tais como pipes, arquivos do filesystem, descritores de arquivos e UNIX sockets.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Estamos baseando a saga em sistema "UNIX-like", mais especificamente GNU/Linux&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ou seja, temos ciência que é possível fazer 2 processos &lt;em&gt;dentro de um mesmo computador&lt;/em&gt; se comunicarem através de UNIX sockets. Mas como fazer dois processos em computadores distintos se comunicarem?&lt;/p&gt;

&lt;p&gt;Entramos então em &lt;strong&gt;Berkeley Sockets&lt;/strong&gt;, que define uma API comum de comunicação utilizando sockets, onde diferentes sockets podem estar no mesmo computador, ou em uma mesma rede local, ou até mesmo em redes diferentes dentro da &lt;em&gt;Internet&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;É aqui que temos a introdução ao TCP, que é um protocolo de comunicação via sockets. Portanto, para fazer um cliente se comunicar com um servidor, é preciso estabelecer &lt;em&gt;endpoints de comunicação&lt;/em&gt;, que são basicamente &lt;strong&gt;sockets&lt;/strong&gt;, e neste caso para a web, vamos utilizar &lt;em&gt;sockets TCP&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Estes sockets são abertos tanto do lado do cliente, quanto no servidor. No servidor, estes sockets são mapeados em descritores de arquivos, que representam um número especial e reservado, também chamado de &lt;strong&gt;porta de comunicação&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj1x249n2k8ajhgvj2fsq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj1x249n2k8ajhgvj2fsq.png" alt="sockets e tcp"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ok Leandro, consegui entender o conceito de sockets e TCP. Mas qual deveria ser o formato da mensagem na web?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Com vocês, o &lt;em&gt;HTTP&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  HTTP
&lt;/h3&gt;

&lt;p&gt;HTTP é um protocolo de formato de mensagem que faz parte da camada de aplicação.&lt;/p&gt;

&lt;p&gt;Com HTTP, a mensagem é definida seguindo padrões de hipertexto, que são basicamente documentos que podem ter ligações com outros documentos em sites diferentes.&lt;/p&gt;

&lt;p&gt;Na web, o padrão segue um formato de &lt;em&gt;headline&lt;/em&gt;, que contém o tipo de pedido, seguido de quebra de linhas com &lt;em&gt;cabeçalhos&lt;/em&gt; de metadados e por fim, opcionalmente e dependendo do tipo de pedido, um &lt;em&gt;corpo&lt;/em&gt; com a mensagem principal contendo majoritariamente HTML, CSS e Javascript.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7d0w16gxgauxlw4bnwe6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7d0w16gxgauxlw4bnwe6.png" alt="tcp &amp;amp; http"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Até agora, passamos por conceitos que formam a web. Como nosso exemplo de web server é bastante simples, estes fundamentos já são o suficiente para entrarmos na próxima seção, que é de fato escrever o web server em Assembly x86.&lt;/p&gt;




&lt;h2&gt;
  
  
  Como funciona um servidor web
&lt;/h2&gt;

&lt;p&gt;Conforme vimos na seção anterior, arquitetura web passa por manipulação de sockets TCP. &lt;/p&gt;

&lt;p&gt;Tal manipulação é feita via &lt;em&gt;chamadas de sistema&lt;/em&gt; (syscalls) no sistema operacional, portanto, para darmos início ao servidor, vamos entender como devem ser criados os sockets a nível do OS.&lt;/p&gt;

&lt;h3&gt;
  
  
  4 syscalls para o resgate
&lt;/h3&gt;

&lt;p&gt;Resumidamente temos que fazer 4 syscalls para termos um server operante, que são:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;socket&lt;/strong&gt;&lt;br&gt;
A syscall &lt;em&gt;socket&lt;/em&gt; é responsável por criar um endpoint de comunicação de rede e retornar um descritor de arquivo (fd) relativo ao endpoint criado.&lt;/p&gt;

&lt;p&gt;Na libc, &lt;em&gt;socket&lt;/em&gt; é referenciada pelo número 41 e tem a seguinte assinatura:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Lembrando que estamos utilizando arquitetura x86_64, ou x64&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;bind&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;bind&lt;/em&gt; atribui nome e porta ao socket previamente criado. Esta syscall na libc responde pelo número 49 e tem a assinatura a seguir:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;sockaddr&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;socklen_t&lt;/span&gt; &lt;span class="n"&gt;addrlen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;listen&lt;/strong&gt;&lt;br&gt;
A syscall &lt;em&gt;listen&lt;/em&gt; marca o socket criado (precisa ser do tipo stream, no caso TCP) para aceitar conexões. É conhecida pelo número 50 e tem a seguinte assinatura em C:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;backlog&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;accept&lt;/strong&gt;&lt;br&gt;
A syscall &lt;em&gt;accept&lt;/em&gt; admite uma conexão de um cliente no socket e cria um &lt;em&gt;novo socket de conexão específico&lt;/em&gt; para aquele cliente. Esta syscall, a princípio, bloqueia o programa e só continua a execução quando uma nova conexão com novo cliente é estabelecida. &lt;/p&gt;

&lt;p&gt;É referenciada pelo número 288 e tem a seguinte assintaura:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;addrlen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Em resumo, tudo o que precisamos para criar um web server, independente do programa, linguagem de programação ou tecnologia, é de chamar estas 4 syscalls.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Não se engane, o teu servidor Express, Rails, Django ou NGINX, faz estas chamadas de sistema por baixo dos panos: &lt;em&gt;socket, bind, listen e accept&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sem mais delongas, vamos ver como tudo isto se aplica naquilo que importa para esta saga: &lt;strong&gt;assembly&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Um server modesto em Assembly
&lt;/h2&gt;

&lt;p&gt;Montar as syscalls para o web server em Assembly não é tão difícil quanto parece. Para começar, vamos fazer a primeira syscall, que é a &lt;em&gt;socket&lt;/em&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Criando o socket
&lt;/h3&gt;

&lt;p&gt;Como de costume, vamos montar as instruções de acordo com o &lt;a href="https://man7.org/linux/man-pages/man2/socket.2.html" rel="noopener noreferrer"&gt;manual&lt;/a&gt; e &lt;a href="https://x64.syscall.sh/" rel="noopener noreferrer"&gt;tabela de syscalls&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Já vimos na seção anterior quais são os números das syscalls e suas respectivas assinaturas na libc&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Iniciamos definindo as constantes, apenas as necessárias para a syscall &lt;em&gt;socket&lt;/em&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;global&lt;/span&gt; &lt;span class="nx"&gt;_start&lt;/span&gt;

&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;syscalls&lt;/span&gt; &lt;span class="nx"&gt;constants&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_socket&lt;/span&gt; &lt;span class="mi"&gt;41&lt;/span&gt;

&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;other&lt;/span&gt; &lt;span class="nx"&gt;constants&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;AF_INET&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SOCK_STREAM&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SOCK_PROTOCOL&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Após isto, vamos reservar 1 byte com a diretiva &lt;code&gt;resb 1&lt;/code&gt; que significa "reservar 1 byte". Este byte será utilizado para armazenar o número do descritor de arquivo que referencia o &lt;em&gt;socket&lt;/em&gt; que vai ser criado.&lt;/p&gt;

&lt;p&gt;Como &lt;strong&gt;não queremos inicializar&lt;/strong&gt; o valor deste byte, não vamos colocar na seção &lt;code&gt;.data&lt;/code&gt; como temos utilizado até o momento na saga, mas sim na seção &lt;code&gt;.bss&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Na seção &lt;code&gt;.data&lt;/code&gt;, ficam apenas dados inicializados&lt;/li&gt;
&lt;li&gt;Na seção &lt;code&gt;.bss&lt;/code&gt;, ficam os dados não-inicializados&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bss&lt;/span&gt;
&lt;span class="nl"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;resb&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Vamos relembrar o layout de memória:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3wznvwyjq68cs1ln7aj3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3wznvwyjq68cs1ln7aj3.png" alt="layout de memória"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como vemos na imagem, a seção &lt;code&gt;.bss&lt;/code&gt; vem a seguir a seção &lt;code&gt;.data&lt;/code&gt;, ou seja, fica em endereços de memória mais altos que a seção &lt;code&gt;.data&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Agora, vamos montar os registradores seguindo a convenção de chamada e a ordem dos parâmetros da função &lt;em&gt;socket&lt;/em&gt; na libc:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;
&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;AF_INET&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SOCK_STREAM&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SOCK_PROTOCOL&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_socket&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt; 
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;domain&lt;/strong&gt;: representa o domínio de comunicação. No caso queremos usar AF_INET, que significa IPv4, e tem o valor 2 conforme especificado no &lt;a href="https://github.com/bminor/glibc/blob/8f58e412b1e26d2c7e65c13a0ce758fbaf18d83f/bits/socket.h#L78" rel="noopener noreferrer"&gt;glibc&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;type&lt;/strong&gt;: representa o tipo de comunicação, que no caso vamos usar SOCK_STREAM que é sequencial, confiável, duplex e baseado em conexão. O valor &lt;a href="https://github.com/bminor/glibc/blob/8f58e412b1e26d2c7e65c13a0ce758fbaf18d83f/bits/socket.h#L42" rel="noopener noreferrer"&gt;conforme glibc&lt;/a&gt; é 1&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;protocol&lt;/strong&gt;: esta opção é usada no caso da utilização de um protocolo em específico. Neste caso, vamos deixar o valor como 0 que é o default para AF_INET e SOCK_STREAM, &lt;em&gt;indicando que se trata de um socket TCP&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Lembrando que existem sockets da família UNIX que não funcionam na camada de rede IP. É possível combinar socket UNIX com SOCK_STREAM, mas neste caso estamos combinando a família AF_INET (IPv4) com o tipo SOCK_STREAM (segmento de bytes, duplex), e esta combinação faz este socket ser TCP. Para mais detalhes sobre sockets, sugiro a leitura de um artigo que escrevi sobre &lt;a href="https://dev.to/leandronsp/building-a-web-server-in-bash-part-i-sockets-2n8b"&gt;UNIX Sockets&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Vamos confirmar com GDB?&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="c"&gt;# Breakpoint na linha &amp;lt;syscall&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;break &lt;/span&gt;22

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; run

&lt;span class="c"&gt;# Confirmando que os registradores estão com os valores corretos&lt;/span&gt;
&lt;span class="c"&gt;# antes da execução da syscall...&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; i r rdi rsi rdx rax
rdi            0x2                 2
rsi            0x1                 1
rdx            0x0                 0
rax            0x29                41

&lt;span class="c"&gt;# Confirmando que `sockfd` continua com o valor zerado&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &amp;amp;sockfd
0x402000 &amp;lt;sockfd&amp;gt;:      0x00000000

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; next


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Após a execução da syscall, podemos ver que o &lt;em&gt;retorno da função&lt;/em&gt;, que representa o descritor de arquivo conforme documentação, está armazenado no registrador RAX (de acordo com a convenção de chamada):&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;
&lt;span class="nx"&gt;rax&lt;/span&gt;            &lt;span class="mh"&gt;0x3&lt;/span&gt;                 &lt;span class="mi"&gt;3&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;sockfd&lt;/span&gt;
&lt;span class="mh"&gt;0x402000&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;:&lt;/span&gt;      &lt;span class="mh"&gt;0x00000003&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Ou seja, após a syscall, temos em &lt;code&gt;sockfd&lt;/code&gt; o número do socket que acabou de ser criado. &lt;/p&gt;

&lt;p&gt;Executando com &lt;em&gt;strace&lt;/em&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;strace ./live

execve&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"./live"&lt;/span&gt;, &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"./live"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;, 0x7ffca20187e0 /&lt;span class="k"&gt;*&lt;/span&gt; 24 vars &lt;span class="k"&gt;*&lt;/span&gt;/&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 0
socket&lt;span class="o"&gt;(&lt;/span&gt;AF_INET, SOCK_STREAM, IPPROTO_IP&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 3
&lt;span class="nb"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;0&lt;span class="o"&gt;)&lt;/span&gt;                                 &lt;span class="o"&gt;=&lt;/span&gt; ?
+++ exited with 0 +++


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Sem erros, &lt;em&gt;yay!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Vamos para a próxima syscall.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fazendo bind no socket
&lt;/h3&gt;

&lt;p&gt;Agora, é o momento de atribuir um endereço e uma porta como endpoint de comunicação para este socket. É para isto que serve a syscall &lt;em&gt;bind&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Analisando a função:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;

&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;sockaddr&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;socklen_t&lt;/span&gt; &lt;span class="n"&gt;addrlen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Podemos ver que um dos argumentos é um &lt;em&gt;ponteiro&lt;/em&gt; para uma struct na memória. Vamos entender melhor cada argumento.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;sockfd&lt;/strong&gt;&lt;br&gt;
Em sockfd vai o inteiro que representa o descritor do socket criado&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;sockaddr **addr&lt;/strong&gt;*&lt;br&gt;
Representa o ponteiro para o endereço de memória que contém uma estrutura de dados que, de acordo com &lt;a href="https://www.gta.ufrj.br/ensino/eel878/sockets/sockaddr_inman.html" rel="noopener noreferrer"&gt;este guia&lt;/a&gt;, contempla: &lt;em&gt;family, port, ip_address, sin_zero&lt;/em&gt;, onde sin_zero é apenas padding de preenchimento de bytes.&lt;/p&gt;

&lt;p&gt;Para arquitetura x64, esta estrutura deve conter 16 bytes no total, onde:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;2 bytes são para a &lt;em&gt;família&lt;/em&gt; de protocolo&lt;/li&gt;
&lt;li&gt;&lt;p&gt;2 bytes para a &lt;em&gt;porta&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;4 bytes para o &lt;em&gt;endereço de IP&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;8 bytes de padding para o &lt;em&gt;sin_zero&lt;/em&gt;, ou seja, preencher os 8 bytes restantes com ZERO&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;addrlen&lt;/strong&gt;: tamanho do sockaddr, e já sabemos que são 16 bytes&lt;/p&gt;

&lt;p&gt;Uma vez entendidos os parâmetros da função, vamos montar a chamada.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_bind&lt;/span&gt; &lt;span class="mi"&gt;49&lt;/span&gt;

&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Data&lt;/span&gt; &lt;span class="nx"&gt;types&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;asm&lt;/span&gt;
&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt;
&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dw&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;word&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt;
&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;doubleword&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt;
&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dq&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;quadword&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;sockaddr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
    &lt;span class="nl"&gt;family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dw&lt;/span&gt; &lt;span class="nx"&gt;AF_INET&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt;
    &lt;span class="nl"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dw&lt;/span&gt; &lt;span class="mh"&gt;0x0BB8&lt;/span&gt;      &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;representa&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;porta&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nl"&gt;ip_address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dd&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;     &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt;
    &lt;span class="nl"&gt;sin_zero&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dq&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;       &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt;

&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bind&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;struct&lt;/span&gt; &lt;span class="nx"&gt;sockaddr&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;socklen_t&lt;/span&gt; &lt;span class="nx"&gt;addrlen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sockaddr&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_bind&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Ao validar com GDB, podemos ver que o &lt;code&gt;sockaddr&lt;/code&gt; está armazenando a estrutura necessária para ser enviada no parâmetro &lt;code&gt;sockaddr *addr&lt;/code&gt; da syscall:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="c"&gt;# Breakpoint na syscall de bind&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;break &lt;/span&gt;38

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; run

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &amp;amp;sockaddr
0x402000 &amp;lt;family&amp;gt;:      0xb80b0002


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Se buscarmos os 2 primeiros bytes, confirmamos que é o valor 2 (repare que está invertido pois é o padrão little-endian da aquitetura x86_64:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x /2xb &amp;amp;sockaddr
0x402000 &amp;lt;family&amp;gt;:      0x02    0x00


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Quanto à porta, queremos que o server responda no número 3000. Portanto, verificamos que os próximos 2 bytes representam a porta:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="c"&gt;# Em hexadecimal, 3000 equivale a 0x0BB8, mas por causa do formato&lt;/span&gt;
&lt;span class="c"&gt;# little-endian da arquitetura x86_64, estamos visualizando 0xB80B&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x /2xb &lt;span class="o"&gt;(&lt;/span&gt;void&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &amp;amp;sockaddr+2
0x402002 &amp;lt;port&amp;gt;:        0xb8    0x0b


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Queremos também que o servidor responda no endereço de IP &lt;code&gt;0.0.0.0&lt;/code&gt;, então os próximos 4 bytes estarão todos a zero:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x /4xb &lt;span class="o"&gt;(&lt;/span&gt;void&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &amp;amp;sockaddr+4
0x402004 &amp;lt;ip_address&amp;gt;:  0x00    0x00    0x00    0x00


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;E, por fim, os 8 bytes restantes representando &lt;em&gt;sin_zero&lt;/em&gt;, todos preenchidos com zero:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x /8xb &lt;span class="o"&gt;(&lt;/span&gt;void&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &amp;amp;sockaddr+8
0x402008 &amp;lt;sin_zero&amp;gt;:    0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Vamos executar com &lt;em&gt;strace&lt;/em&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;strace ./live

execve&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"./live"&lt;/span&gt;, &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"./live"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;, 0x7ffd51ed4650 /&lt;span class="k"&gt;*&lt;/span&gt; 24 vars &lt;span class="k"&gt;*&lt;/span&gt;/&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 0
socket&lt;span class="o"&gt;(&lt;/span&gt;AF_INET, SOCK_STREAM, IPPROTO_IP&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 3
&lt;span class="nb"&gt;bind&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;3, &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;sa_family&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;AF_INET, &lt;span class="nv"&gt;sin_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;htons&lt;span class="o"&gt;(&lt;/span&gt;47115&lt;span class="o"&gt;)&lt;/span&gt;, &lt;span class="nv"&gt;sin_addr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;inet_addr&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"0.0.0.0"&lt;/span&gt;&lt;span class="o"&gt;)}&lt;/span&gt;, 16&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 0
&lt;span class="nb"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;0&lt;span class="o"&gt;)&lt;/span&gt;                                 &lt;span class="o"&gt;=&lt;/span&gt; ?
+++ exited with 0 +++


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Ouch! Apesar da função &lt;em&gt;bind&lt;/em&gt; ter retornado 0 indicando que não houve erros, temos um pequeno problema. Repare que a &lt;em&gt;porta&lt;/em&gt; não está sendo mapeada para o número &lt;strong&gt;3000&lt;/strong&gt;, e sim para &lt;strong&gt;47115&lt;/strong&gt;, conforme vemos em &lt;em&gt;htons(47115)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Entendendo a implicação de endianess na syscall bind&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;htons&lt;/code&gt; é uma função de rede utilizada para converter a ordem dos bytes do programa antes de serem utilizados na rede. Como a internet utiliza big-endian, esta função converte a ordem utilizada na arquitetura (no caso da x86_64, little-endian) para o formato big-endian da rede.&lt;/p&gt;

&lt;p&gt;Entretanto &lt;em&gt;htons(47115)&lt;/em&gt; não é o valor que queremos. O que precisamos é que o mapeamendo seja &lt;em&gt;htons(3000)&lt;/em&gt;. Por quê isto está acontecendo?&lt;/p&gt;

&lt;p&gt;O valor que colocamos em hexadecimal representando &lt;em&gt;3000&lt;/em&gt; é &lt;em&gt;0x0BB8&lt;/em&gt;, mas se prestarmos atenção no GBD, o valor de fato armazenado está com os bytes invertidos para little-endian, que é &lt;em&gt;0xB80B&lt;/em&gt;. Ocorre que &lt;code&gt;0xB80B&lt;/code&gt; em decimal é &lt;strong&gt;47115&lt;/strong&gt;!!!!!! Aí que está o problema!&lt;/p&gt;

&lt;p&gt;Precisamos então inverter os bytes no programa, e assim sendo o valor que será passado para a função htons fica corrigido.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;sockaddr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
    &lt;span class="nl"&gt;family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dw&lt;/span&gt; &lt;span class="nx"&gt;AF_INET&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt;
    &lt;span class="nl"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dw&lt;/span&gt; &lt;span class="mh"&gt;0xB80B&lt;/span&gt;      &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;aqui&lt;/span&gt; &lt;span class="nx"&gt;invertemos&lt;/span&gt; &lt;span class="nx"&gt;os&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nl"&gt;ip_address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dd&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;     &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt;
    &lt;span class="nl"&gt;sin_zero&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dq&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;       &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt;
&lt;span class="p"&gt;....&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;E analisando novamente com GDB:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="c"&gt;# Agora sim, apesar de estar invertido, é exatamente este valor que&lt;/span&gt;
&lt;span class="c"&gt;# queremos que seja passado para htons: 0x0BB8 em decimal é 3000&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x /2xb &lt;span class="o"&gt;(&lt;/span&gt;void&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &amp;amp;sockaddr+2
0x402002 &amp;lt;port&amp;gt;:        0x0b    0xb8


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Executando novamente com &lt;em&gt;strace&lt;/em&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;strace ./live

execve&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"./live"&lt;/span&gt;, &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"./live"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;, 0x7ffd51ed4650 /&lt;span class="k"&gt;*&lt;/span&gt; 24 vars &lt;span class="k"&gt;*&lt;/span&gt;/&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 0
socket&lt;span class="o"&gt;(&lt;/span&gt;AF_INET, SOCK_STREAM, IPPROTO_IP&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 3
&lt;span class="nb"&gt;bind&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;3, &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;sa_family&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;AF_INET, &lt;span class="nv"&gt;sin_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;htons&lt;span class="o"&gt;(&lt;/span&gt;3000&lt;span class="o"&gt;)&lt;/span&gt;, &lt;span class="nv"&gt;sin_addr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;inet_addr&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"0.0.0.0"&lt;/span&gt;&lt;span class="o"&gt;)}&lt;/span&gt;, 16&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 0
&lt;span class="nb"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;0&lt;span class="o"&gt;)&lt;/span&gt;                                 &lt;span class="o"&gt;=&lt;/span&gt; ?
+++ exited with 0 +++


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Superb!&lt;/em&gt; Podemos ver que a syscall &lt;em&gt;bind&lt;/em&gt; foi executada com os parâmetros corretamente, inclusive o &lt;code&gt;htons(3000)&lt;/code&gt;, então retornando &lt;em&gt;0&lt;/em&gt;, que indica que não houve qualquer erro.&lt;/p&gt;

&lt;h3&gt;
  
  
  Preparando para receber conexões
&lt;/h3&gt;

&lt;p&gt;Próximo passo consiste em preparar o socket para receber conexões, que basicamente é chamar a função &lt;code&gt;listen&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_listen&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;BACKLOG&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;backlog&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;BACKLOG&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_listen&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Onde &lt;em&gt;BACKLOG&lt;/em&gt; significa a quantidade de conexões "pendentes" no socket. Executamos com &lt;em&gt;strace&lt;/em&gt; e:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;strace ./live

execve&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"./live"&lt;/span&gt;, &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"./live"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;, 0x7ffe6b4eea30 /&lt;span class="k"&gt;*&lt;/span&gt; 24 vars &lt;span class="k"&gt;*&lt;/span&gt;/&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 0
socket&lt;span class="o"&gt;(&lt;/span&gt;AF_INET, SOCK_STREAM, IPPROTO_IP&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 3
&lt;span class="nb"&gt;bind&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;3, &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;sa_family&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;AF_INET, &lt;span class="nv"&gt;sin_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;htons&lt;span class="o"&gt;(&lt;/span&gt;3000&lt;span class="o"&gt;)&lt;/span&gt;, &lt;span class="nv"&gt;sin_addr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;inet_addr&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"0.0.0.0"&lt;/span&gt;&lt;span class="o"&gt;)}&lt;/span&gt;, 16&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 0
listen&lt;span class="o"&gt;(&lt;/span&gt;3, 2&lt;span class="o"&gt;)&lt;/span&gt;                            &lt;span class="o"&gt;=&lt;/span&gt; 0
&lt;span class="nb"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;0&lt;span class="o"&gt;)&lt;/span&gt;                                 &lt;span class="o"&gt;=&lt;/span&gt; ?
+++ exited with 0 +++


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Que noite maravilhosa!&lt;/em&gt; Listen funcionou lindamente, afinal, é uma função muito simples. Agora, hora de aceitar conexões de clientes no socket.&lt;/p&gt;

&lt;h3&gt;
  
  
  Chegou o momento de aceitar clientes
&lt;/h3&gt;

&lt;p&gt;O grande momento chegou. Vamos montar as instruções da syscall &lt;em&gt;accept&lt;/em&gt;, que de acordo com a função em libc, recebe um socket como primeiro argumento e os demais são opcionais.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_accept&lt;/span&gt; &lt;span class="mi"&gt;288&lt;/span&gt;

&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accept&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;struct&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;addrlen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;              &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="err"&gt;ã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;precisa&lt;/span&gt; &lt;span class="nx"&gt;estabelecer&lt;/span&gt; &lt;span class="nx"&gt;um&lt;/span&gt; &lt;span class="nx"&gt;addr&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;              &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="err"&gt;ã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;precisa&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;tamanho&lt;/span&gt; &lt;span class="nx"&gt;uma&lt;/span&gt; &lt;span class="nx"&gt;vez&lt;/span&gt; &lt;span class="nx"&gt;que&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="err"&gt;ã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;addr&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_accept&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Se executarmos com GDB, podemos ver que o resultado da syscall fica bloqueado até que uma conexão seja feita:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="c"&gt;# Breakpoint na syscall de socket&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;break &lt;/span&gt;55

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; run
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; next


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;O programa está parado na syscall de socket, aguardando resposta do &lt;strong&gt;kernel&lt;/strong&gt;. Para que o kernel responda e o programa continue a execução, é preciso realizar um pedido usando um HTTP client, e neste caso vamos usar o &lt;em&gt;curl&lt;/em&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;curl localhost:3000


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Repare que o programa continuou a execução. Vamos ver a resposta que está em RAX:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; i r rax
rax            0x4                 4

&lt;span class="c"&gt;# Um número diferente do sockfd, que é o socket criado pelo server&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &amp;amp;sockfd
0x402010 &amp;lt;sockfd&amp;gt;:      0x00000003



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Podemos ver que é um número diferente (RAX contém 4 e sockfd contém 3). De acordo com a documentação, este é o número do descritor que representa um novo socket criado para comunicação entre &lt;em&gt;um cliente específico e o servidor&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Vamos mover o valor de RAX para R8, apenas para preservar o socket, uma vez que RAX será usado novamente por outras syscalls de accept:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;             &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Resposta do servidor e fechamento da conexão
&lt;/h3&gt;

&lt;p&gt;Uma outra coisa importante a se fazer é &lt;strong&gt;fechar a conexão&lt;/strong&gt; com este socket do cliente depois de ter processado e respondido a requisição.&lt;/p&gt;

&lt;p&gt;Vamos implementar a subrotina &lt;code&gt;.write&lt;/code&gt;, que escreve a resposta na conexão (socket) do cliente:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CR&lt;/span&gt; &lt;span class="mh"&gt;0xD&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;LF&lt;/span&gt; &lt;span class="mh"&gt;0xA&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
    &lt;span class="nl"&gt;headline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"HTTP/1.1 200 OK"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;LF&lt;/span&gt;
    &lt;span class="nl"&gt;content_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: text/html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;LF&lt;/span&gt;
    &lt;span class="nl"&gt;content_length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"Content-Length: 22"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;LF&lt;/span&gt;
    &lt;span class="nl"&gt;crlf&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="nx"&gt;CR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;LF&lt;/span&gt;
    &lt;span class="nl"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;"&lt;/span&gt;
&lt;span class="nl"&gt;responseLen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;equ&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;write&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;bf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;bfLen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;responseLen&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;No exemplo acima, assumimos que a string de resposta HTTP aponta para uma estrutura na memória, definida em &lt;code&gt;.data&lt;/code&gt;. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Atenção para CR (carriage return), LF (line feed) que são constantes que representam &lt;code&gt;\r\n&lt;/code&gt; que são separadores de linhas definidos pelo protocolo HTTP&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Agora, definir a subrotina &lt;code&gt;.close&lt;/code&gt;, que fecha a conexão com o cliente:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_close&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;close&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_close&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Ligando tudo no &lt;em&gt;accept&lt;/em&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;
&lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accept&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;struct&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;addrlen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;              &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="err"&gt;ã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;precisa&lt;/span&gt; &lt;span class="nx"&gt;estabelecer&lt;/span&gt; &lt;span class="nx"&gt;um&lt;/span&gt; &lt;span class="nx"&gt;addr&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;              &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="err"&gt;ã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;precisa&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;tamanho&lt;/span&gt; &lt;span class="nx"&gt;uma&lt;/span&gt; &lt;span class="nx"&gt;vez&lt;/span&gt; &lt;span class="nx"&gt;que&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="err"&gt;ã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;addr&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_accept&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;             &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;write&lt;/span&gt;             &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;escreve&lt;/span&gt; &lt;span class="nx"&gt;no&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;close&lt;/span&gt;             &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;fecha&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt;
    &lt;span class="nx"&gt;jmp&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt;               &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;termina&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;programa&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;E agora, vamos executar o programa com &lt;em&gt;strace&lt;/em&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;strace ./live

execve&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"./live"&lt;/span&gt;, &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"./live"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;, 0x7ffd811567c0 /&lt;span class="k"&gt;*&lt;/span&gt; 24 vars &lt;span class="k"&gt;*&lt;/span&gt;/&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 0
socket&lt;span class="o"&gt;(&lt;/span&gt;AF_INET, SOCK_STREAM, IPPROTO_IP&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 3
&lt;span class="nb"&gt;bind&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;3, &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;sa_family&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;AF_INET, &lt;span class="nv"&gt;sin_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;htons&lt;span class="o"&gt;(&lt;/span&gt;3000&lt;span class="o"&gt;)&lt;/span&gt;, &lt;span class="nv"&gt;sin_addr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;inet_addr&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"0.0.0.0"&lt;/span&gt;&lt;span class="o"&gt;)}&lt;/span&gt;, 16&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 0
listen&lt;span class="o"&gt;(&lt;/span&gt;3, 2&lt;span class="o"&gt;)&lt;/span&gt;                            &lt;span class="o"&gt;=&lt;/span&gt; 0
accept4&lt;span class="o"&gt;(&lt;/span&gt;3, NULL, NULL, 0


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;primeiro foi feita a syscall &lt;em&gt;socket&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;a seguir foi feito o &lt;em&gt;bind&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;depois o &lt;em&gt;listen&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;e por fim, o &lt;em&gt;accept&lt;/em&gt; ficou bloqueado a espera de uma requisição&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Em outra janela, vamos fazer a requisição:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;curl localhost:3000
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;E no servidor, a saída do strace no final ficou assim:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

write&lt;span class="o"&gt;(&lt;/span&gt;4, &lt;span class="s2"&gt;"HTTP/1.1 200 OK&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s2"&gt;Content-Type: t"&lt;/span&gt;..., 86&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 86
close&lt;span class="o"&gt;(&lt;/span&gt;4&lt;span class="o"&gt;)&lt;/span&gt;                                &lt;span class="o"&gt;=&lt;/span&gt; 0
&lt;span class="nb"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;0&lt;span class="o"&gt;)&lt;/span&gt;                                 &lt;span class="o"&gt;=&lt;/span&gt; ?
+++ exited with 0 +++


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Escreveu a resposta com &lt;code&gt;write&lt;/code&gt;, fechou a conexão com &lt;code&gt;close&lt;/code&gt;, e depois terminou o programa com &lt;code&gt;exit&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Como não ficar feliz?&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Mas o servidor deve ficar em loop, não?
&lt;/h3&gt;

&lt;p&gt;Sim, o servidor deve ficar em loop, portanto ao invés de fazer o &lt;code&gt;jmp .exit&lt;/code&gt;, fazemos &lt;code&gt;jmp .accept&lt;/code&gt; na última linha da procedure:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accept&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;struct&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;addrlen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;              &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="err"&gt;ã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;precisa&lt;/span&gt; &lt;span class="nx"&gt;estabelecer&lt;/span&gt; &lt;span class="nx"&gt;um&lt;/span&gt; &lt;span class="nx"&gt;addr&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;              &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="err"&gt;ã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;precisa&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;tamanho&lt;/span&gt; &lt;span class="nx"&gt;uma&lt;/span&gt; &lt;span class="nx"&gt;vez&lt;/span&gt; &lt;span class="nx"&gt;que&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="err"&gt;ã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;addr&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_accept&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;             &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;write&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;close&lt;/span&gt;
    &lt;span class="nx"&gt;jmp&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accept&lt;/span&gt;             &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;--&lt;/span&gt; &lt;span class="nx"&gt;MUDAN&lt;/span&gt;&lt;span class="err"&gt;Ç&lt;/span&gt;&lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="nx"&gt;AQUI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mant&lt;/span&gt;&lt;span class="err"&gt;é&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt; &lt;span class="nx"&gt;em&lt;/span&gt; &lt;span class="nx"&gt;loop&lt;/span&gt; &lt;span class="nx"&gt;infinito&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Assim, o server nunca termina, e quando uma conexão com um cliente é fechada, voltamos no início do loop e ficamos a espera de nova conexão na syscall &lt;em&gt;accept&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Código final do server:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;global&lt;/span&gt; &lt;span class="nx"&gt;_start&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_socket&lt;/span&gt; &lt;span class="mi"&gt;41&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_bind&lt;/span&gt; &lt;span class="mi"&gt;49&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_listen&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_accept&lt;/span&gt; &lt;span class="mi"&gt;288&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_close&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;AF_INET&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SOCK_STREAM&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SOCK_PROTOCOL&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;BACKLOG&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;CR&lt;/span&gt; &lt;span class="mh"&gt;0xD&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;LF&lt;/span&gt; &lt;span class="mh"&gt;0xA&lt;/span&gt;

&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Data&lt;/span&gt; &lt;span class="nx"&gt;types&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;asm&lt;/span&gt;
&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt;
&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;word&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt;
&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;doubleword&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt;
&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;quadword&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;sockaddr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
    &lt;span class="nl"&gt;family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dw&lt;/span&gt; &lt;span class="nx"&gt;AF_INET&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt;
    &lt;span class="nl"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dw&lt;/span&gt; &lt;span class="mh"&gt;0xB80B&lt;/span&gt;      &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;47115&lt;/span&gt; &lt;span class="nx"&gt;big&lt;/span&gt; &lt;span class="nx"&gt;endian&lt;/span&gt; &lt;span class="nx"&gt;becomes&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt; &lt;span class="nx"&gt;little&lt;/span&gt; &lt;span class="nx"&gt;endian&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nl"&gt;ip_address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dd&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;     &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt;
    &lt;span class="nl"&gt;sin_zero&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dq&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;       &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt;
&lt;span class="nl"&gt;sockaddrLen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;equ&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;sockaddr&lt;/span&gt;
&lt;span class="nl"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
    &lt;span class="nl"&gt;headline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"HTTP/1.1 200 OK"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;LF&lt;/span&gt;
    &lt;span class="nl"&gt;content_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: text/html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;LF&lt;/span&gt;
    &lt;span class="nl"&gt;content_length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"Content-Length: 22"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;LF&lt;/span&gt;
    &lt;span class="nl"&gt;crlf&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="nx"&gt;CR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;LF&lt;/span&gt;
    &lt;span class="nl"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;"&lt;/span&gt;
&lt;span class="nl"&gt;responseLen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;equ&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bss&lt;/span&gt;
&lt;span class="nl"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;resb&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;
&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;AF_INET&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SOCK_STREAM&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SOCK_PROTOCOL&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_socket&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt; 
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bind&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;struct&lt;/span&gt; &lt;span class="nx"&gt;sockaddr&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;socklen_t&lt;/span&gt; &lt;span class="nx"&gt;addrlen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sockaddr&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sockaddrLen&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_bind&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;backlog&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;BACKLOG&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_listen&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accept&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;struct&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;addrlen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;              &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="err"&gt;ã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;precisa&lt;/span&gt; &lt;span class="nx"&gt;estabelecer&lt;/span&gt; &lt;span class="nx"&gt;um&lt;/span&gt; &lt;span class="nx"&gt;addr&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;              &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="err"&gt;ã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;precisa&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;tamanho&lt;/span&gt; &lt;span class="nx"&gt;uma&lt;/span&gt; &lt;span class="nx"&gt;vez&lt;/span&gt; &lt;span class="nx"&gt;que&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="err"&gt;ã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;addr&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_accept&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;             &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;write&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;close&lt;/span&gt;
    &lt;span class="nx"&gt;jmp&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accept&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;write&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;bf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;bfLen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;responseLen&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;close&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;r8&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_close&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Executando tudo com &lt;em&gt;strace&lt;/em&gt; e temos:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;strace ./live

execve&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"./live"&lt;/span&gt;, &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"./live"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;, 0x7fff9fde7840 /&lt;span class="k"&gt;*&lt;/span&gt; 24 vars &lt;span class="k"&gt;*&lt;/span&gt;/&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 0
socket&lt;span class="o"&gt;(&lt;/span&gt;AF_INET, SOCK_STREAM, IPPROTO_IP&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 3
&lt;span class="nb"&gt;bind&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;3, &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;sa_family&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;AF_INET, &lt;span class="nv"&gt;sin_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;htons&lt;span class="o"&gt;(&lt;/span&gt;3000&lt;span class="o"&gt;)&lt;/span&gt;, &lt;span class="nv"&gt;sin_addr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;inet_addr&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"0.0.0.0"&lt;/span&gt;&lt;span class="o"&gt;)}&lt;/span&gt;, 16&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 0
listen&lt;span class="o"&gt;(&lt;/span&gt;3, 2&lt;span class="o"&gt;)&lt;/span&gt;                            &lt;span class="o"&gt;=&lt;/span&gt; 0
accept4&lt;span class="o"&gt;(&lt;/span&gt;3, NULL, NULL, 0&lt;span class="o"&gt;)&lt;/span&gt;               &lt;span class="o"&gt;=&lt;/span&gt; 4
write&lt;span class="o"&gt;(&lt;/span&gt;4, &lt;span class="s2"&gt;"HTTP/1.1 200 OK&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s2"&gt;Content-Type: t"&lt;/span&gt;..., 86&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 86
close&lt;span class="o"&gt;(&lt;/span&gt;4&lt;span class="o"&gt;)&lt;/span&gt;                                &lt;span class="o"&gt;=&lt;/span&gt; 0
accept4&lt;span class="o"&gt;(&lt;/span&gt;3, NULL, NULL, 0&lt;span class="o"&gt;)&lt;/span&gt;               &lt;span class="o"&gt;=&lt;/span&gt; 4
write&lt;span class="o"&gt;(&lt;/span&gt;4, &lt;span class="s2"&gt;"HTTP/1.1 200 OK&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s2"&gt;Content-Type: t"&lt;/span&gt;..., 86&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 86
close&lt;span class="o"&gt;(&lt;/span&gt;4&lt;span class="o"&gt;)&lt;/span&gt;                                &lt;span class="o"&gt;=&lt;/span&gt; 0
accept4&lt;span class="o"&gt;(&lt;/span&gt;3, NULL, NULL, 0&lt;span class="o"&gt;)&lt;/span&gt;               &lt;span class="o"&gt;=&lt;/span&gt; 4
write&lt;span class="o"&gt;(&lt;/span&gt;4, &lt;span class="s2"&gt;"HTTP/1.1 200 OK&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s2"&gt;Content-Type: t"&lt;/span&gt;..., 86&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 86
close&lt;span class="o"&gt;(&lt;/span&gt;4&lt;span class="o"&gt;)&lt;/span&gt;                                &lt;span class="o"&gt;=&lt;/span&gt; 0
accept4&lt;span class="o"&gt;(&lt;/span&gt;3, NULL, NULL, 0


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;No lado do cliente:&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;p&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl localhost:3000&lt;br&gt;
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl localhost:3000&lt;br&gt;
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl localhost:3000&lt;br&gt;
&amp;lt;h1&amp;gt;Hello, World!&amp;lt;/h1&amp;gt;&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Com vocês, o web browser&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;Esta saga não teria nenhuma graça se não fosse pra ser executada em um &lt;em&gt;web browser&lt;/em&gt;, afinal estamos falando de um &lt;strong&gt;web server&lt;/strong&gt;, não?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqm4v5vqi8jw5578sajjy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqm4v5vqi8jw5578sajjy.png" alt="final hello world"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Incrivelmente chegamos no final da construção de um modesto web server. Aqui aprendemos conceitos sobre sockets, TCP e HTTP, com uma pitada leve de HTML.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Fala aí, quem não já conhecia a tag H1 do HTML? kk&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Para além de termos visto sobre as syscalls de rede &lt;em&gt;socket, bind, listen e accept&lt;/em&gt; em Assembly.&lt;/p&gt;

&lt;p&gt;Ainda não chegamos ao fim da saga, pelo que no próximo artigo iremos abordar a criação de &lt;strong&gt;threads&lt;/strong&gt; e aprender sobre alocação dinâmica de memória para as threads.&lt;/p&gt;

&lt;p&gt;Stay tuned!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Agradecimentos a &lt;a href="https://x.com/rodrigogbranco" rel="noopener noreferrer"&gt;Rodrigo Gonçalves de Branco&lt;/a&gt; por ter revisado este artigo com o devido rigor&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;p&gt;&lt;br&gt;
Building a web server in Bash&lt;br&gt;
&lt;a href="https://dev.to/leandronsp/series/19120"&gt;https://dev.to/leandronsp/series/19120&lt;/a&gt;&lt;br&gt;
OSI Model&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/OSI_model" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/OSI_model&lt;/a&gt;&lt;br&gt;
TCP&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Transmission_Control_Protocol" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Transmission_Control_Protocol&lt;/a&gt;&lt;br&gt;
Berkeley Sockets&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Berkeley_sockets" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Berkeley_sockets&lt;/a&gt;&lt;br&gt;
HTTP&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/HTTP" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/HTTP&lt;/a&gt;&lt;br&gt;
struct sockaddr_in&lt;br&gt;
&lt;a href="https://www.gta.ufrj.br/ensino/eel878/sockets/sockaddr_inman.html" rel="noopener noreferrer"&gt;https://www.gta.ufrj.br/ensino/eel878/sockets/sockaddr_inman.html&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>assembly</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>Construindo um web server em Assembly x86, parte IV, um assembly modesto</title>
      <dc:creator>Leandro Proença</dc:creator>
      <pubDate>Mon, 13 May 2024 11:33:03 +0000</pubDate>
      <link>https://dev.to/leandronsp/construindo-um-web-server-em-assembly-x86-parte-iv-um-assembly-modesto-oif</link>
      <guid>https://dev.to/leandronsp/construindo-um-web-server-em-assembly-x86-parte-iv-um-assembly-modesto-oif</guid>
      <description>&lt;p&gt;Uma vez que temos &lt;a href="https://dev.to/leandronsp/construindo-um-web-server-em-assembly-x86-parte-iii-codigo-de-maquina-bgk"&gt;uma compreensão&lt;/a&gt; sobre sistema binário, hexadecimal, ASCII e código de máquina, chegou o grande momento de entrarmos no assunto principal desta saga: &lt;strong&gt;assembly&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Vamos iniciar transportando o "Hello, World" feito em código de máquina para assembly x86 e, posteriormente, abordar um exemplo de programa que recebe argumento da linha de comando.&lt;/p&gt;

&lt;p&gt;Ao longo deste artigo vamos aprender a base de conceitos como rótulos, segmentos de memória, &lt;em&gt;muito gdb&lt;/em&gt;, layout de memória, &lt;strong&gt;muita stack&lt;/strong&gt;, procedures (subrotinas, ou &lt;em&gt;funções&lt;/em&gt;), loops, condicionais, flags, tipos de registradores e etc&lt;/p&gt;

&lt;p&gt;Aperte os cintos, pois este será um artigo bem extenso. Sugiro ao leitor, - que tem interesse em aprender na prática com esta saga -, que tenha o ambiente preparado e que execute cada exemplo seguindo os passos aqui descritos.&lt;/p&gt;

&lt;p&gt;Sem mais delongas, vamos ao que importa.&lt;/p&gt;




&lt;h2&gt;
  
  
  Agenda
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
Humanizar é preciso

&lt;ul&gt;
&lt;li&gt;Mnemonics&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Assemblers&lt;/li&gt;

&lt;li&gt;

Nosso primeiro programa

&lt;ul&gt;
&lt;li&gt;A chamada de sistema exit&lt;/li&gt;
&lt;li&gt;Arquivos Objeto&lt;/li&gt;
&lt;li&gt;Linker&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Depurando o programa

&lt;ul&gt;
&lt;li&gt;O utilitário size&lt;/li&gt;
&lt;li&gt;Debugging com gdb&lt;/li&gt;
&lt;li&gt;Rastreando execução com strace&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Evoluindo nosso primeiro programa&lt;br&gt;


&lt;ul&gt;
&lt;li&gt;Alocando bytes para "Hello, World"&lt;/li&gt;
&lt;li&gt;Adicionando a chamada de sistema write&lt;/li&gt;
&lt;li&gt;Layout de memória&lt;/li&gt;
&lt;li&gt;Definindo constantes&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Um programa mais sofisticado

&lt;ul&gt;
&lt;li&gt;Definindo labels&lt;/li&gt;
&lt;li&gt;Desvio de fluxo com jump&lt;/li&gt;
&lt;li&gt;Desvio de fluxo com call&lt;/li&gt;
&lt;li&gt;Brincando com pilhas&lt;/li&gt;
&lt;li&gt;Calculando tamanho dinamicamente com loop&lt;/li&gt;
&lt;li&gt;RFLAGS&lt;/li&gt;
&lt;li&gt;Botando mais pilha no negócio&lt;/li&gt;
&lt;li&gt;Depurando o programa final com strace&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Falando um pouco de registradores

&lt;ul&gt;
&lt;li&gt;Propósito dos registradores&lt;/li&gt;
&lt;li&gt;Registradores de propósito geral&lt;/li&gt;
&lt;li&gt;Registradores especiais&lt;/li&gt;
&lt;li&gt;Precisamos sempre utilizar todos os 64 bits?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Uma side note sobre stack frames&lt;/li&gt;

&lt;li&gt;Conclusão&lt;/li&gt;

&lt;li&gt;Referências&lt;/li&gt;

&lt;/ul&gt;




&lt;blockquote&gt;
&lt;p&gt;Antes de iniciar, quero novamente deixar uma menção especial ao excelente &lt;a href="https://www.youtube.com/watch?v=Ej6U-qk0bdE&amp;amp;list=PLXoSGejyuQGohd0arC7jRBqVdQqf5GqKJ" rel="noopener noreferrer"&gt;curso gratuito de Assembly x86&lt;/a&gt; do &lt;a href="https://www.youtube.com/@debxp" rel="noopener noreferrer"&gt;Blau Araújo&lt;/a&gt;. É importante reforçar o quanto este material dele é necessário e foi crucial para que eu pudesse fundamentar diversos conceitos explorados ao longo desta saga&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Humanizar é preciso
&lt;/h2&gt;

&lt;p&gt;Como vimos no artigo anterior, CPU só entende código de máquina:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 0A  ; Hello, World

BF 01 00 00 00     ; RDI ⬅️ 1
48 BE 00 10 40     ; RSI ⬅️ 0x401000
BA 0D 00 00 00     ; RDX ⬅️ 13
B8 01 00 00 00     ; RAX ⬅️ 1
0F 05              ; SYSCALL
BF 00 00 00 00     ; RDI ⬅️ 0
B8 3C 00 00 00     ; RAX ⬅️ 60
0F 05              ; SYSCALL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Entretanto, para uma pessoa desenvolvedora manter um programa em código de máquina, é preciso ter muita paciência e atenção ao detalhe, pelo que também manter programas assim é muito propenso a bugs.&lt;/p&gt;

&lt;p&gt;Precisamos de alguma forma, representar cada instrução em código de máquina em uma linguagem mais "human-friendly". &lt;/p&gt;

&lt;h3&gt;
  
  
  Mnemonics
&lt;/h3&gt;

&lt;p&gt;É aí que entram os &lt;strong&gt;mnemonics&lt;/strong&gt;, que são uma forma textual de representar informações visando facilitar a memorização para o cérebro humano.&lt;/p&gt;

&lt;p&gt;Ao invés de trabalharmos com &lt;code&gt;BF 01 00 00 00&lt;/code&gt;, podemos trocar por &lt;code&gt;MOV RDI, 1&lt;/code&gt;, que significa:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;estou movendo o valor imediato 1 para o registrador RDI&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;E assim vamos &lt;em&gt;montando&lt;/em&gt; instrução por instrução, tal e qual faríamos com código de máquina, mas utilizando uma &lt;em&gt;linguagem&lt;/em&gt; de fácil memorização.&lt;/p&gt;

&lt;p&gt;Mas a CPU não entende essa "linguagem". Temos de construir um &lt;em&gt;programa&lt;/em&gt; que faz a &lt;em&gt;tradução&lt;/em&gt; de mnemonics para &lt;em&gt;código de máquina&lt;/em&gt;, ou seja, de &lt;code&gt;MOV RSI, 1&lt;/code&gt; para &lt;code&gt;BF 01 00 00 00&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm7zzy20fad71wg461cpt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm7zzy20fad71wg461cpt.png" alt="assembly" width="800" height="245"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Estamos falando de &lt;em&gt;montadores&lt;/em&gt;, ou simplesmente &lt;strong&gt;assemblers&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Assemblers
&lt;/h2&gt;

&lt;p&gt;Ao longo do tempo, foram desenvolvidos diversos assemblers para diferentes arquiteturas. &lt;/p&gt;

&lt;p&gt;Para arquitetura x86, há diversos assemblers já construídos, GNU Assembler (as), NASM, FASM, pra mencionar alguns.&lt;/p&gt;

&lt;p&gt;Assemblers para esta arquitetura em específico podem seguir 2 tipos de sintaxe que são predominantes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AT&amp;amp;T, desenvolvida pela AT&amp;amp;T corporation&lt;/li&gt;
&lt;li&gt;Intel, desenvolvida pela Intel&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nesta saga, vamos focar no Assembler &lt;strong&gt;NASM&lt;/strong&gt; para arquitetura X86 64-bits (x64), com &lt;em&gt;sintaxe Intel&lt;/em&gt; e rodando em sistema GNU/Linux, como já mencionamos algumas vezes em artigos anteriores.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Arquitetura x86_64 (x64)&lt;/li&gt;
&lt;li&gt;Sistema Operacional GNU/Linux (Ubuntu)&lt;/li&gt;
&lt;li&gt;Assembler NASM 2.16.01 &lt;/li&gt;
&lt;li&gt;GNU ld 2.38 (ligador, ou linker)&lt;/li&gt;
&lt;li&gt;Debugger GNU gdb 12.1&lt;/li&gt;
&lt;li&gt;strace 5.16 (tracing de syscalls)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Uma vez que definimos as ferramentas utilizadas, vamos seguir traduzindo o "Hello, World" para asm x86 enquanto entendemos o uso de cada uma delas.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A partir de agora, quando me referir a Assembly ou simplesmente "asm", leia-se &lt;em&gt;Assembly x86_64&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Nosso primeiro programa
&lt;/h2&gt;

&lt;p&gt;Em Assembly, todo programa deve ter um ponto de entrada, também chamado de &lt;strong&gt;entry point&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;global&lt;/span&gt; &lt;span class="nx"&gt;_start&lt;/span&gt;

&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="err"&gt;ó&lt;/span&gt;&lt;span class="nx"&gt;digo&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;programa&lt;/span&gt; &lt;span class="nx"&gt;vai&lt;/span&gt; &lt;span class="nx"&gt;aqui&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E a primeira coisa que nosso programa vai fazer é sair:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;kkkkkkkkkk&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  A chamada de sistema exit
&lt;/h3&gt;

&lt;p&gt;Brincadeiras à parte, a chamada de sistema que precisamos executar é a &lt;code&gt;exit&lt;/code&gt;, definida da seguinte forma no &lt;code&gt;glibc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;_exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com isto, temos de seguir a lógica para montar as instruções tal como fizemos com os opcodes, que seguindo  &lt;a href="https://x64.syscall.sh/" rel="noopener noreferrer"&gt;a mesma tabela de syscalls&lt;/a&gt;, é:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;nome da syscall vai em RAX&lt;/li&gt;
&lt;li&gt;primeiro argumento (o status de erro) vai em RDI
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;global&lt;/span&gt; &lt;span class="nx"&gt;_start&lt;/span&gt;

&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;  &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;nome&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;syscall&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;       
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este programa simplesmente faz aquilo que mencionamos no artigo anterior: &lt;em&gt;que todo programa deve terminar&lt;/em&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;mov rdi, 0&lt;/code&gt; move o valor imediato 1 para o registrador RDI; vai representar o error code da syscall &lt;strong&gt;exit&lt;/strong&gt;: 0 para término sem erros&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mov rax, 60&lt;/code&gt; move o valor imediato 60 para o registrador RAX; vai representar o nome da syscall em si, &lt;strong&gt;exit&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;syscall&lt;/code&gt; faz a chamada de sistema da syscall &lt;strong&gt;exit&lt;/strong&gt;, definida em RAX&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para que o programa seja compilado, precisamos primeiro fazer a "montagem" das instruções com NASM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;nasm &lt;span class="nt"&gt;-f&lt;/span&gt; elf64 hello.asm &lt;span class="nt"&gt;-o&lt;/span&gt; hello.o
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-f elf64&lt;/code&gt;: arquitetura de destino, x64&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;hello.asm&lt;/code&gt; input, ou seja, o arquivo que contém o código fonte&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-o hello.o&lt;/code&gt;: define saída para o arquivo &lt;code&gt;hello.o&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Mas o quê é este arquivo &lt;code&gt;hello.o&lt;/code&gt;?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Arquivos objeto
&lt;/h3&gt;

&lt;p&gt;Arquivo objeto (&lt;strong&gt;Object File&lt;/strong&gt;) é um arquivo que contém código de máquina gerado por um assembler ou compilador.&lt;/p&gt;

&lt;p&gt;Porém este arquivo ainda não é um &lt;em&gt;executável&lt;/em&gt; final, porque podemos querer combinar com outros arquivos objeto e bibliotecas nativas do SO.&lt;/p&gt;

&lt;p&gt;A partir deste arquivo, que geralmente tem a extensão &lt;code&gt;.o&lt;/code&gt;, podemos utilizar outro programa para "ligar" com outros arquivos, se necessário, no intuito de gerar um arquivo com código de máquina final e executável.&lt;/p&gt;

&lt;p&gt;Este programa se chama &lt;strong&gt;linker&lt;/strong&gt;, pelo que utilizaremos a versão padrão do &lt;code&gt;ld&lt;/code&gt; que vem com o GNU no nosso sistema operacional GNU/Linux.&lt;/p&gt;

&lt;h3&gt;
  
  
  Linker
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Linker&lt;/em&gt; é o programa responsável por, a partir de um ou mais arquivos objeto, gerar um arquivo final executável com o código de máquina.&lt;/p&gt;

&lt;p&gt;Como já geramos anteriormente o arquivo objeto &lt;code&gt;hello.o&lt;/code&gt; utilizando o assembler NASM, podemos concluir o processo de compilação do nosso programa fonte asm x86 com &lt;code&gt;ld&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ld hello.o &lt;span class="nt"&gt;-o&lt;/span&gt; hello
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E agora, vamos rodar o binário final executável &lt;code&gt;hello&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;./hello
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$?&lt;/span&gt;
0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Hurray!&lt;/em&gt; Nosso primeiro programa em Assembly concluído com sucesso!&lt;/p&gt;

&lt;p&gt;Contudo, vamos lembrar de um ponto importante que vimos na parte II da saga: que o &lt;em&gt;programa e seus dados ficam na memória&lt;/em&gt;. Queremos entender &lt;strong&gt;o que está acontecendo na memória&lt;/strong&gt; com este simples programa. &lt;/p&gt;




&lt;h2&gt;
  
  
  Depurando o programa
&lt;/h2&gt;

&lt;p&gt;Uma das etapas mais importantes, senão a mais  importante, em desenvolvimento de software, é a &lt;em&gt;depuração&lt;/em&gt; (ou debugging, em inglês). &lt;/p&gt;

&lt;p&gt;Depurar é o ato de conseguir interceptar a execução do programa, analisar o estado, alterar o estado, adicionar pontos de parada (breakpoints) entre outras técnicas. &lt;/p&gt;

&lt;p&gt;O processo de depuração também consiste em analisar a saída do programa como um todo, seu tamanho e trace de chamadas no sistema operacional.&lt;/p&gt;

&lt;h3&gt;
  
  
  O utilitário size
&lt;/h3&gt;

&lt;p&gt;Vamos iniciar o processo de depuração do nosso programa analisando o tamanho, com o utilitário GNU &lt;em&gt;size&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;size hello

   text    data     bss     dec     hex filename
     12       0       0      12       c hello
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Mas o quê significa "text, data, bss, etc"?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Cada programa no sistema operacional é dividido em &lt;em&gt;seções&lt;/em&gt;, que representam alguma característica para o sistema operacional. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flv9edus1e9nxw4b24cxq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flv9edus1e9nxw4b24cxq.png" alt="layout de memória" width="385" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;text&lt;/strong&gt;&lt;br&gt;
Esta seção contém todo o código fonte do programa, e assim o SO sabe que precisa buscar esta seção na memória principal&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;data&lt;/strong&gt;&lt;br&gt;
Seção de dados inicializados na memória&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;bss&lt;/strong&gt; &lt;br&gt;
Seção de dados não-inicializados na memória&lt;/p&gt;

&lt;p&gt;O comando &lt;strong&gt;size&lt;/strong&gt; traz justamente o tamanho (em bytes) de cada seção. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;dec&lt;/code&gt; e &lt;code&gt;hex&lt;/code&gt; não são seções, são apenas a representação do valor total (em bytes) tanto em decimal quanto hexadecimal&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;text&lt;/code&gt;: esta seção contém todo o código fonte do nosso programa, também chamado de "texto"&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data&lt;/code&gt;: seção de dados inicializados, logo a seguir neste artigos entramos em detalhe&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;bss&lt;/code&gt;: seção de dados não-inicializados, logo a seguir também falaremos deste&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dec&lt;/code&gt;: o tamanho total em decimal&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;hex&lt;/code&gt;: o tamanho total em hexadecimal&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nosso programa por enquanto só tem a seção text, que é exatamente todo o código a partir do rótulo &lt;code&gt;_start&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Nossa, Leandro, nosso programa tem apenas 12 bytes?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Aparentemente sim. Vamos confirmar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-lh&lt;/span&gt; hello

...... 4.6K ... hello
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Como assim o arquivo tem 4,6Kb? O programa não ocupa 12 bytes apenas? &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Bom, isto ocorre por causa dos headers que são adicionados pelo linker, que contém informação relevante para que o sistema operacional possa admitir a execução do arquivo.&lt;/p&gt;

&lt;p&gt;Vamos novamente utilizar o comando &lt;code&gt;size&lt;/code&gt; mas desta vez:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;size &lt;span class="nt"&gt;--format&lt;/span&gt; sysv &lt;span class="nt"&gt;--radix&lt;/span&gt; 16 hello

hello  :
section   size       addr
.text    0xc   0x401000
Total    0xc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A opção &lt;code&gt;--format&lt;/code&gt; indica o formato &lt;code&gt;sysv&lt;/code&gt; que traz também os símbolos. E a opção &lt;code&gt;--radix 16&lt;/code&gt; permite visualizar o tamanho de cada seção em hexadecimal.&lt;/p&gt;

&lt;p&gt;Na seção size, &lt;code&gt;0xc&lt;/code&gt; representa o número 12 em decimal. Nada de novo aqui. Mas se repararmos na coluna &lt;code&gt;addr&lt;/code&gt;, temos um valor hexadecimal para a seção text (0x401000).&lt;/p&gt;

&lt;p&gt;Já vimos isto no artigo anterior, que &lt;code&gt;0x401000&lt;/code&gt; se referia ao endereço em hexadecimal de memória virtual que indica o início do programa, lembra?&lt;/p&gt;

&lt;p&gt;Hora de confirmar isto com uma análise mais profunda na depuração, chegou o momento de utilizarmos GNU &lt;em&gt;gdb&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Debugging com GDB
&lt;/h3&gt;

&lt;p&gt;GDB é um depurador (&lt;em&gt;debugger&lt;/em&gt; em inglês) que permite ver o que está acontecendo dentro de um programa &lt;em&gt;em execução&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Com um depurador, podemos analisar as informações estáticas contidas no binário do programa, estabelecer &lt;em&gt;breakpoints&lt;/em&gt; (pontos de parada) em qualquer parte do código, executar e analisar mudanças de estado do programa durante sua execução.&lt;/p&gt;

&lt;p&gt;Para habilitar o programa com &lt;code&gt;gdb&lt;/code&gt;, precisamos montar o programa com a opção &lt;code&gt;-g&lt;/code&gt;, que exporta símbolos necessários para depuração:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;nasm &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; elf64 hello.asm &lt;span class="nt"&gt;-o&lt;/span&gt; hello.o
&lt;span class="nv"&gt;$ &lt;/span&gt;ld hello.o &lt;span class="nt"&gt;-o&lt;/span&gt; hello
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Podemos verificar os símbolos exportados no binário com o comando size novamente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;size &lt;span class="nt"&gt;--format&lt;/span&gt; sysv &lt;span class="nt"&gt;--radix&lt;/span&gt; 16 hello

hello  :
section           size       addr
.text              0xc   0x401000
.debug_aranges    0x30        0x0
.debug_info       0x75        0x0
.debug_abbrev     0x1d        0x0
.debug_line       0x3d        0x0
Total            0x10b

&lt;span class="c"&gt;##############&lt;/span&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-lh&lt;/span&gt; hello
...... 5.1K ... hello
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como demonstrado acima, o binário agora contém seções adicionais de "debug" que serão utilizadas pelo &lt;em&gt;gdb&lt;/em&gt;, e consequentemente o tamanho do programa teve um acréscimo de &lt;del&gt;500MB&lt;/del&gt; 512 bytes!&lt;/p&gt;

&lt;p&gt;Sem mais delongas, vamos entrar no &lt;code&gt;gdb&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;gdb &lt;span class="nt"&gt;--quiet&lt;/span&gt;

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E agora, dentro do shell gdb, podemos utilizar diversos comandos de depuração. O comando &lt;code&gt;help&lt;/code&gt; traz a lista de &lt;em&gt;classes de comandos&lt;/em&gt; disponíveis:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;help

...
aliases -- User-defined aliases of other commands.
breakpoints -- Making program stop at certain points.
data -- Examining data.
files -- Specifying and examining files.
internals -- Maintenance commands.
obscure -- Obscure features.
running -- Running the program.
stack -- Examining the stack.
status -- Status inquiries.
support -- Support facilities.
text-user-interface -- TUI is the GDB text based interface.
tracepoints -- Tracing of program execution without stopping the program.
user-defined -- User-defined commands.
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Para o escopo deste artigo vamos utilizar apenas alguns comandos para depuração, mas a lista de comandos disponíveis é &lt;a href="https://visualgdb.com/gdbreference/commands/" rel="noopener noreferrer"&gt;gigante&lt;/a&gt;. Deixo o desafio ao leitor para se aventurar com o &lt;code&gt;help&lt;/code&gt; do gdb e brincar de depurar qualquer binário executável&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Como queremos depurar o binário &lt;em&gt;hello&lt;/em&gt;, podemos carregar os símbolos utilizando o comando &lt;code&gt;file&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; file hello
Reading symbols from hello...
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O comando &lt;code&gt;info files&lt;/code&gt; traz alguns insights:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; info files
Symbols from &lt;span class="s2"&gt;"/code/asm-x64/hello"&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
Local &lt;span class="nb"&gt;exec &lt;/span&gt;file:
        &lt;span class="sb"&gt;`&lt;/span&gt;/code/asm-x64/hello&lt;span class="s1"&gt;', file type elf64-x86-64.
        Entry point: 0x401000
        0x0000000000401000 - 0x000000000040100c is .text
(gdb)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Que interessante! O entry point do programa começa justamente em &lt;code&gt;0x401000&lt;/code&gt;, que é o que está definido na seção &lt;code&gt;.text&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Para visualizar o código fonte do programa, utilizamos o comando &lt;code&gt;list&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; list
1       global _start
2
3       _start:
4               mov rdi, 0   &lt;span class="p"&gt;;&lt;/span&gt; error code
5               mov rax, 60  &lt;span class="p"&gt;;&lt;/span&gt; SYS_exit
6               syscall
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Lembrando que o programa ainda não está em execução, estamos apenas analisando o binário executável com o gdb&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Com o comando &lt;code&gt;x&lt;/code&gt;, de &lt;em&gt;examine&lt;/em&gt;, podemos examinar o rótulo &lt;code&gt;_start&lt;/code&gt; que é o ponto de entrada do programa:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x _start
0x401000 &amp;lt;_start&amp;gt;:      0x000000bf
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se quisermos executar o programa, podemos fazê-lo com o comando &lt;code&gt;run&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; run
Starting program: /code/asm-x64/hello
&lt;span class="o"&gt;[&lt;/span&gt;Inferior 1 &lt;span class="o"&gt;(&lt;/span&gt;process 7991&lt;span class="o"&gt;)&lt;/span&gt; exited normally]
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Entretanto, podemos definir breakpoints antes de executar, assim temos controle do estado do programa &lt;strong&gt;em execução&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Aqui, definimos um ponto de parada no rótulo _start_&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;break &lt;/span&gt;_start
Breakpoint 1 at 0x401000: file hello.asm, line 4.

&lt;span class="c"&gt;# Info sobre breakpoints&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; info breakpoints
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000000000401000 hello.asm:4
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora sim, vamos executar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; run
Starting program: /code/asm-x64/hello

Breakpoint 1, _start &lt;span class="o"&gt;()&lt;/span&gt; at hello.asm:4
4               mov rdi, 0   &lt;span class="p"&gt;;&lt;/span&gt; error code
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O programa está parado na linha 4 como solicitado. Esta linha no código &lt;strong&gt;não foi avaliada&lt;/strong&gt;, pelo que podemos analisar e alterar o estado do programa:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Neste momento o valor no registrador RDI está 0 (default)&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; info register rdi
rdi            0x0                 0

&lt;span class="c"&gt;# Mudamos o valor do registrador para 42&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nv"&gt;$rdi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 42

&lt;span class="c"&gt;# Agora verificamos que foi modificado diretamente do GDB&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; info register rdi
rdi            0x2a                42
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para avaliar a linha atual, utilizamos o comando &lt;code&gt;next&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; next
5               mov rax, 60  &lt;span class="p"&gt;;&lt;/span&gt; SYS_exit

&lt;span class="c"&gt;# E podemos agora verificar que o valor de RDI foi modificado para 0, &lt;/span&gt;
&lt;span class="c"&gt;# conforme descrito no programa&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; info register rdi
rdi            0x0                 0
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Poderíamos continuar indo linha a linha com &lt;code&gt;next&lt;/code&gt;, ou então continuar a execução do programa com &lt;code&gt;continue&lt;/code&gt; que pára no próximo ponto de parada ou executa todas as instruções que faltam até terminar o programa.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Inicia execução e pára no primeiro breakpoint definido&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; run
Starting program: /Users/leandronsp/Documents/code/asm-x64/hello

Breakpoint 1, _start &lt;span class="o"&gt;()&lt;/span&gt; at hello.asm:4
4               mov rdi, 0   &lt;span class="p"&gt;;&lt;/span&gt; error code

&lt;span class="c"&gt;# Continua execução. Neste caso termina o programa pois&lt;/span&gt;
&lt;span class="c"&gt;# não há mais breakpoints a partir deste ponto&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;continue
&lt;/span&gt;Continuing.
&lt;span class="o"&gt;[&lt;/span&gt;Inferior 1 &lt;span class="o"&gt;(&lt;/span&gt;process 8000&lt;span class="o"&gt;)&lt;/span&gt; exited normally]
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pronto, terminamos a demonstração do primeiro programa com &lt;code&gt;gdb&lt;/code&gt;. Para sair, utilizamos o comando &lt;code&gt;exit&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rastreando execução com strace
&lt;/h3&gt;

&lt;p&gt;O utilitário &lt;code&gt;strace&lt;/code&gt; permite rastrear todas as chamadas de sistema e sinais que um programa faz. É bastante útil quando queremos saber o que pode ter acontecido com determinada &lt;em&gt;syscall&lt;/em&gt;, quais parâmetros foram enviados e o que a syscall retornou.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;strace ./hello

execve&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"./hello"&lt;/span&gt;, &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"./hello"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;, 0x7ffc504b5710 /&lt;span class="k"&gt;*&lt;/span&gt; 24 vars &lt;span class="k"&gt;*&lt;/span&gt;/&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 0
&lt;span class="nb"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;0&lt;span class="o"&gt;)&lt;/span&gt;                                 &lt;span class="o"&gt;=&lt;/span&gt; ?
+++ exited with 0 +++
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vamos entender a saída do &lt;strong&gt;strace&lt;/strong&gt; por partes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;execve("./hello", ["./hello"], 0x7ffc504b5710 /_ 24 vars _/) = 0:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;execve&lt;/code&gt; é uma chamada do Linux que executa um determinado programa&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;./hello&lt;/code&gt; é o caminho para o programa que será executado&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;["./hello"]&lt;/code&gt; é a lista de argumentos passados para o programa. Como só há o nome do programa (que entra na lista &lt;em&gt;ARGV&lt;/em&gt;), indica que este programa não recebe argumentos extras na linha de comando&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;0x7ffc504b5710&lt;/code&gt; é o endereço de memória onde as variáveis de ambiente do processo em execução estão armazenadas&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/* 24 vars */&lt;/code&gt; indica que há 24 variáveis de ambiente definidas no shell atual&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;=0&lt;/code&gt; é o resultado da chamada &lt;code&gt;execve&lt;/code&gt;, o que significa que foi bem-sucedido e executado com sucesso&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;exit(0) = ?:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;exit&lt;/code&gt; é a chamada de sistema (syscall) feita no sistema operacional, e geralmente é definida no &lt;code&gt;libc&lt;/code&gt;, sendo no caso de sistema GNU, &lt;code&gt;glibc&lt;/code&gt;. Foi o valor &lt;em&gt;60&lt;/em&gt; passado para o registrador RAX, lembra?&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;(0)&lt;/code&gt; é o parâmetro passado para a função, que neste caso foi o que determinamos no registrador RDI, indicando que nosso programa em execução vai terminar &lt;em&gt;sem erros&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;= ?&lt;/code&gt; indica que o resultado da chamada de sistema não é conhecido, ou seja não houve um retorno &lt;em&gt;explícito&lt;/em&gt; de valor da chamada de sistema&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;+++ exited with 0 +++:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;+++&lt;/code&gt; sinaliza o início de uma mensagem de saída do strace&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;exited with 0&lt;/code&gt; indica que o programa terminou sem erros&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;+++&lt;/code&gt; sinaliza o fim da mensagem de saída&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Uma vez que entendemos como depurar nosso programa, podemos evolui-lo para imprimir a mensagem "Hello, World" na saída do terminal.&lt;/p&gt;




&lt;h2&gt;
  
  
  Evoluindo nosso primeiro programa
&lt;/h2&gt;

&lt;p&gt;Vamos agora evoluir o programa anterior para que possamos imprimir a mensagem "Hello, World" na saída padrão &lt;code&gt;STDOUT&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Para isto, conforme vimos na parte III da saga, "Código de Máquina", vamos por partes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Alocando bytes para "Hello, World"
&lt;/h3&gt;

&lt;p&gt;Precisamos primeiro definir os bytes de cada caracter da string em &lt;em&gt;hexadecimal&lt;/em&gt; de acordo com a tabela ASCII, que resulta em &lt;code&gt;48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 0A&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;0x48 para "H", 0x65 para "e", 0x6C para "l" e assim por diante...&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Portanto, se quisermos evoluir o primeiro programa que contém apenas a syscall &lt;code&gt;exit&lt;/code&gt;, podemos começar por definir a string utilizando a diretiva &lt;code&gt;db&lt;/code&gt; que significa &lt;em&gt;define byte&lt;/em&gt;, utilizando o endereço do primeiro byte em um rótulo que iremos chamar de &lt;em&gt;msg&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;global&lt;/span&gt; &lt;span class="nx"&gt;_start&lt;/span&gt;

&lt;span class="nl"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="mh"&gt;0x48&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x65&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x6C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x6C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x6F&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;\&lt;/span&gt;
        &lt;span class="mh"&gt;0x2C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x57&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x6F&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x72&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;\&lt;/span&gt;
        &lt;span class="mh"&gt;0x6C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0xA&lt;/span&gt;

&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;  &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;       
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Antes de sair adicionando mais código, vamos utilizar o &lt;code&gt;gdb&lt;/code&gt; para analisar o que esta mudança provoca na memória:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Examinar o que há no rótulo msg&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x msg
0x401000 &amp;lt;msg&amp;gt;: 0x6c6c6548

&lt;span class="c"&gt;# Examinar o que há no rótulo _start&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x _start
0x40100d &amp;lt;_start&amp;gt;:      0x000000bf
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ora ora, o que temos aqui? &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;msg&lt;/code&gt; aponta para o endereço &lt;code&gt;0x401000&lt;/code&gt; que era o endereço usado pelo &lt;code&gt;_start&lt;/code&gt; no nosso programa anterior&lt;/li&gt;
&lt;li&gt;e agora &lt;code&gt;_start&lt;/code&gt; aponta para outro endereço, &lt;code&gt;0x40100d&lt;/code&gt; que está &lt;strong&gt;13 bytes&lt;/strong&gt; ("d" em hexa) acima de &lt;code&gt;msg&lt;/code&gt;, exatamente os 13 bytes da string "Hello, World" adicionado com quebra de linha!!!!!1&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Superb! Mas o que significa o valor &lt;code&gt;0x6c6c6548&lt;/code&gt;?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Se analisarmos com calma, dá pra perceber que se trata dos caracteres da string em ASCII segundo o que foi definido no programa. Mas eles estão &lt;em&gt;invertidos&lt;/em&gt;, lembra de endianness que foi explicado no artigo anterior?&lt;/p&gt;

&lt;p&gt;Então, esta arquitetura segue o padrão little-endian, onde os bytes são armazenados na ordem inversa, do menos relevante (expoentes menores da base 2) para o mais relevante (expoentes maiores).&lt;/p&gt;

&lt;p&gt;Voltando ao gdb, podemos confirmar que todos os bytes da string estão alocados trabalhando com ponteiros de 4 em 4 bytes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x msg
0x401000 &amp;lt;msg&amp;gt;: 0x6c6c6548 &lt;span class="p"&gt;;&lt;/span&gt; Hell

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x msg+4
0x401004:       0x57202c6f &lt;span class="p"&gt;;&lt;/span&gt; o, W

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x msg+8
0x401008:       0x646c726f &lt;span class="p"&gt;;&lt;/span&gt; orld
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ou então, o comando &lt;code&gt;x&lt;/code&gt; permite passar uma quantidade junto com o formato de apresentação, por exemplo queremos que traga os primeiros &lt;em&gt;13 hexabytes&lt;/em&gt; a partir do ponteiro &lt;strong&gt;msg&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x/13xb msg
0x401000 &amp;lt;msg&amp;gt;: 0x48    0x65    0x6c    0x6c    0x6f    0x2c    0x20    0x57
0x401008:       0x6f    0x72    0x6c    0x64    0x0a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exatamente os hexadecimais da string "Hello, World" com quebra de linha!&lt;/p&gt;

&lt;p&gt;Mas em Assembly, não precisamos definir os bytes de uma string em hexadecimal. Podemos utilizar os &lt;em&gt;quotes literais&lt;/em&gt;, assim o programa fica menos verboso e o assembler faz o processo de traduzir o caracter para o hexadecimal da tabela ASCII:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"Hello, World"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0xA&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Não conseguimos representar a quebra de linha dentro de quotes literais, então vamos manter esta com 0xA&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Adicionando a chamada de sistema write
&lt;/h3&gt;

&lt;p&gt;Como já sabemos, o programa precisa utilizar a syscall &lt;code&gt;write&lt;/code&gt; para escrever na saída, que está definida da seguinte forma no &lt;code&gt;glibc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;ssize_t&lt;/span&gt; &lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;[.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;nome da syscall vai em RAX&lt;/li&gt;
&lt;li&gt;primeiro argumento (file descriptor, no caso o &lt;em&gt;STDOUT&lt;/em&gt;) vai em RDI&lt;/li&gt;
&lt;li&gt;segundo argumento (ponteiro para o início do buffer) vai em RSI&lt;/li&gt;
&lt;li&gt;terceiro argumento (quantidade de bytes a serem escritos) vai em RDX
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;global&lt;/span&gt; &lt;span class="nx"&gt;_start&lt;/span&gt;

&lt;span class="nl"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"Hello, World"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0xA&lt;/span&gt;
&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Chamada&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;sistema&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;glibc&lt;/span&gt; &lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;ssize_t&lt;/span&gt; &lt;span class="nx"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                             &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nb"&gt;void&lt;/span&gt; &lt;span class="nx"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;[.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; 
                             &lt;span class="nx"&gt;size_t&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;ponteiro&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="err"&gt;í&lt;/span&gt;&lt;span class="nx"&gt;cio&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt;  &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;quantidade&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;serem&lt;/span&gt; &lt;span class="nx"&gt;escritos&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;nome&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;syscall&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;      &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;chamada&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;sistema&lt;/span&gt;

    &lt;span class="o"&gt;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Chamada&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;sistema&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;glibc&lt;/span&gt; &lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;void&lt;/span&gt; &lt;span class="nx"&gt;_exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;erro&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;sa&lt;/span&gt;&lt;span class="err"&gt;í&lt;/span&gt;&lt;span class="nx"&gt;da&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;  &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;nome&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;syscall&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;           
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ao compilar o programa com &lt;code&gt;nasm + ld&lt;/code&gt;, seguindo a mesma lógica do primeiro programa, temos de fato a saída tão desejada:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ./hello
Hello, World
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Yay! que dia maravilhoso!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Vamos ver como fica o trace disso tudo agora?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;strace ./hello

execve&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"./hello"&lt;/span&gt;, &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"./hello"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;, 0x7fff139437f0 /&lt;span class="k"&gt;*&lt;/span&gt; 24 vars &lt;span class="k"&gt;*&lt;/span&gt;/&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 0
write&lt;span class="o"&gt;(&lt;/span&gt;1, &lt;span class="s2"&gt;"Hello, World&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;, 13Hello, World
&lt;span class="o"&gt;)&lt;/span&gt;          &lt;span class="o"&gt;=&lt;/span&gt; 13
&lt;span class="nb"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;0&lt;span class="o"&gt;)&lt;/span&gt;                                 &lt;span class="o"&gt;=&lt;/span&gt; ?
+++ exited with 0 +++
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wow, podemos ver que, agora, o programa executa primeiro a syscall &lt;code&gt;write&lt;/code&gt;, que retorna o valor &lt;code&gt;13&lt;/code&gt;, que é quantidade de bytes escritos &lt;em&gt;com sucesso&lt;/em&gt;; e a seguir executa a syscall &lt;code&gt;exit&lt;/code&gt;, também com sucesso, indicando que nosso programa imprime a string na saída e termina sem erros.&lt;/p&gt;

&lt;p&gt;Como ficou o tamanho do programa agora?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;size hello

   text    data     bss     dec     hex filename
     52       0       0      52      34 hello
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hmm, parece que a seção &lt;code&gt;text&lt;/code&gt; aumentou de tamanho, que é a adição da string "Hello, World" e das instruções para a syscall &lt;code&gt;write&lt;/code&gt;. Mas por enquanto é a única seção existente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;size &lt;span class="nt"&gt;--format&lt;/span&gt; sysv &lt;span class="nt"&gt;--radix&lt;/span&gt; 16 hello

hello  :
section           size       addr
.text             0x34   0x401000
&lt;span class="o"&gt;(&lt;/span&gt;omitindo seções de debug&lt;span class="o"&gt;)&lt;/span&gt;
Total            0x139

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Podemos ver que a string definida no rótulo &lt;code&gt;msg&lt;/code&gt;, que começa no endereço &lt;code&gt;0x401000&lt;/code&gt; está contida na seção &lt;code&gt;.text&lt;/code&gt;. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Isto é um problema?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Mais ou menos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;O rótulo &lt;code&gt;msg&lt;/code&gt; , que é um "dado", contendo a string, está definido num endereço de memória &lt;strong&gt;anterior&lt;/strong&gt;, ou seja, em endereço de memória mais baixo em direção a 0&lt;/li&gt;
&lt;li&gt;O rótulo &lt;code&gt;_start&lt;/code&gt;, que é o início do programa, está definido num endereço &lt;strong&gt;posterior&lt;/strong&gt;, ou seja, em endereço de memória mais alto com relação à string&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No sistema operacional, todo programa é encapsulado em um processo tal como vimos no artigo anterior. E sendo um processo, é submetido a um "layout" que deve seguir algumas regras.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layout de memória
&lt;/h3&gt;

&lt;p&gt;Fazendo paralelo com a saída do comando &lt;code&gt;size&lt;/code&gt;, a memória do programa segue um layout, que basicamente contém as seguintes seções, ou &lt;em&gt;segmentos&lt;/em&gt; de memória:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;text&lt;/li&gt;
&lt;li&gt;data&lt;/li&gt;
&lt;li&gt;bss&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Já falamos disto anteriormente neste artigo, mas basicamente na seção &lt;code&gt;text&lt;/code&gt; fica todo o código, instruções do programa.&lt;/p&gt;

&lt;p&gt;Na seção &lt;code&gt;data&lt;/code&gt;, ficam dados inicializados (aqui deveria estar a nossa string). E na seção &lt;code&gt;bss&lt;/code&gt; vão os dados não-inicializados, mas já com uma área pré-alocada na memória.&lt;/p&gt;

&lt;p&gt;Em termos de &lt;strong&gt;espaço virtual de memória&lt;/strong&gt; do programa, a seção &lt;code&gt;text&lt;/code&gt; deve ficar nos endereços de memória mais baixos, próximos ao entry point &lt;code&gt;0x401000&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Com isto, o programa deve crescer a partir da seção &lt;code&gt;text&lt;/code&gt; em direção a &lt;code&gt;data&lt;/code&gt; e &lt;code&gt;bss&lt;/code&gt;, dos menores endereços de memória para os maiores (da esquerda pra direita):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;text -&amp;gt; data -&amp;gt; bss
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ou então, analisando numa imagem em vertical, de baixo pra cima:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyy0iqqbaz3ox378srcw6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyy0iqqbaz3ox378srcw6.png" alt="layout de memoria 2" width="385" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Existem mais seções no layout mas vamos adicioná-las à medida que avançamos no artigo. Por agora, como nosso programa está tratando dados (&lt;code&gt;msg&lt;/code&gt;) como &lt;code&gt;text&lt;/code&gt;, devemos colocar na seção correta, que é &lt;code&gt;data&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;global&lt;/span&gt; &lt;span class="nx"&gt;_start&lt;/span&gt;

&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;segmento&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;dados&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;endere&lt;/span&gt;&lt;span class="err"&gt;ç&lt;/span&gt;&lt;span class="nx"&gt;os&lt;/span&gt; &lt;span class="nx"&gt;mais&lt;/span&gt; &lt;span class="nx"&gt;altos&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"Hello, World"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0xA&lt;/span&gt;

&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;segmento&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;texto&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;endere&lt;/span&gt;&lt;span class="err"&gt;ç&lt;/span&gt;&lt;span class="nx"&gt;os&lt;/span&gt; &lt;span class="nx"&gt;mais&lt;/span&gt; &lt;span class="nx"&gt;baixos&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;
&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;ponteiro&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="err"&gt;í&lt;/span&gt;&lt;span class="nx"&gt;cio&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt;  &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;quantidade&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;serem&lt;/span&gt; &lt;span class="nx"&gt;escritos&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;nome&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;syscall&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;      &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;chamada&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;sistema&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;erro&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;sa&lt;/span&gt;&lt;span class="err"&gt;í&lt;/span&gt;&lt;span class="nx"&gt;da&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;  &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;nome&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;syscall&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com &lt;code&gt;gdb&lt;/code&gt;, podemos conferir que agora estamos obedecendo o layout de memória estabelecido para o programa:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x _start
0x401000 &amp;lt;_start&amp;gt;:      0x000000bf

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &amp;amp;msg
0x402000 &amp;lt;msg&amp;gt;: 0x6c6c6548
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note que para acessar &lt;code&gt;msg&lt;/code&gt; no segmento de dados, precisamos examinar através da &lt;em&gt;referência&lt;/em&gt;, com o operador &lt;code&gt;&amp;amp;&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Definindo constantes
&lt;/h3&gt;

&lt;p&gt;Em Assembly podemos definir constantes que podem ser reutilizadas em diversas partes do programa, evitando assim alguma redundância com repetição de código e valores.&lt;/p&gt;

&lt;p&gt;A diretiva &lt;code&gt;%define&lt;/code&gt; permite definir valores constantes tanto para string quanto números:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;global&lt;/span&gt; &lt;span class="nx"&gt;_start&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;EXIT_STATUS&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;NEWLINE&lt;/span&gt; &lt;span class="mh"&gt;0xA&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"Hello, World"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NEWLINE&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;
&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt; 
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;      

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;EXIT_STATUS&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Podemos também definir uma constante baseada em uma expressão aritmética. Por exemplo, ao invés de deixarmos o tamanho em bytes com valor fixo &lt;em&gt;13&lt;/em&gt;, podemos fazer que isto seja calculado com base em aritmética de ponteiros na memória com a diretiva &lt;code&gt;equ&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"Hello, World"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NEWLINE&lt;/span&gt;
&lt;span class="nl"&gt;msgLen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;equ&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O operador &lt;code&gt;$&lt;/code&gt; tem o ponteiro de memória para o último byte no programa, no caso o &lt;code&gt;NEWLINE&lt;/code&gt; definido na linha anterior. Ao subtrair do ponteiro &lt;code&gt;msg&lt;/code&gt; com a expressão &lt;code&gt;$ - msg&lt;/code&gt;, temos o tamanho em bytes calculado e desta forma não precisa ser um valor fixo em RDX:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;global&lt;/span&gt; &lt;span class="nx"&gt;_start&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;EXIT_STATUS&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;NEWLINE&lt;/span&gt; &lt;span class="mh"&gt;0xA&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"Hello, World"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NEWLINE&lt;/span&gt;
&lt;span class="nl"&gt;msgLen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;equ&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;
&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt; 
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;msgLen&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;      

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;EXIT_STATUS&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Wonderful! Nosso programa agora tá muito mais elegante!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Ufa, parece que terminamos o nosso primeiro programa e este por si só já foi uma jornada longa. Mas tenha um pouco mais de paciência, &lt;strong&gt;vem comigo&lt;/strong&gt;, pois chegou o momento de escrevermos um programa um pouco mais sofisticado. &lt;/p&gt;

&lt;p&gt;Hora de explorar mais funcionalidades no Assembly e entrar no mundo da &lt;em&gt;stack&lt;/em&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Um programa mais sofisticado
&lt;/h2&gt;

&lt;p&gt;Vamos começar por um programa simples e evoluindo conforme depuramos e entendemos a memória. Ao fim, o programa deve ser capaz de receber um nome através dos argumentos da linha de comando e imprimir "Hi, &lt;code&gt;&amp;lt;nome&amp;gt;&lt;/code&gt;". &lt;/p&gt;

&lt;p&gt;Desejado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;./greeting Leandro
Hi, Leandro
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Definindo labels
&lt;/h3&gt;

&lt;p&gt;Já sabemos que o programa precisa imprimir "Hi, " alguma coisa. Então as instruções pra syscall &lt;code&gt;write&lt;/code&gt; são necessárias, e já fazendo uso de constantes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;global&lt;/span&gt; &lt;span class="nx"&gt;_start&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"Hi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0xA&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;
&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;greet&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este programa imprime "Hi" apenas. Mas podemos melhorar a organização separando em blocos com algum valor &lt;em&gt;semântico&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;separar o bloco de &lt;code&gt;exit&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;separar o bloco de &lt;code&gt;write&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Assembly emprega o conceito de &lt;strong&gt;labels&lt;/strong&gt;, que são rótulos, mas que podem ser definidas em qualquer parte do código. Utilizando o caracter &lt;em&gt;ponto&lt;/em&gt; (&lt;code&gt;.&lt;/code&gt;), o programa fica bem mais expressivo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;global&lt;/span&gt; &lt;span class="nx"&gt;_start&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"Hi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0xA&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;
&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;greet&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assim como qualquer rótulo, o programa vai executando top-down. O que fizemos aqui foi apenas colocar rótulos em determinadas partes do programa, mas sem &lt;em&gt;alterar seu fluxo de execução&lt;/em&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Desvio de fluxo com jump
&lt;/h3&gt;

&lt;p&gt;Se quisermos alterar o fluxo de execução, podemos utilizar a instrução &lt;code&gt;JMP&lt;/code&gt; que altera o fluxo do programa para outro ponto, continuando &lt;em&gt;a partir desde novo ponto&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;global&lt;/span&gt; &lt;span class="nx"&gt;_start&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"Hi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0xA&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;
&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Faz&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;jump&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;label&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sem&lt;/span&gt; &lt;span class="nx"&gt;passar&lt;/span&gt; &lt;span class="nx"&gt;por&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt;
    &lt;span class="nx"&gt;jmp&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;greet&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Faz&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;jump&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;label&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;caso&lt;/span&gt; &lt;span class="nx"&gt;contr&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt;&lt;span class="nx"&gt;rio&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;programa&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="err"&gt;ã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;terminaria&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;forma&lt;/span&gt; &lt;span class="nx"&gt;adequada&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt; &lt;span class="nx"&gt;programa&lt;/span&gt; &lt;span class="nx"&gt;deve&lt;/span&gt; &lt;span class="nx"&gt;terminar&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;jmp&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este foi um exemplo bastante simples com jump e desvio de fluxo. Mas é possível também desviar o fluxo, executar a lógica do novo fluxo, e &lt;em&gt;retornar&lt;/em&gt; ao ponto anterior.&lt;/p&gt;

&lt;p&gt;Entretanto, para que isto funcione, vamos imaginar uma possível solução:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;definir algum registrador "especial" que guarda sempre o ponteiro da próxima instrução&lt;/li&gt;
&lt;li&gt;antes de desviar o fluxo, guardar o endereço de memória da próxima instrução do programa em alguma &lt;em&gt;estrutura de dados&lt;/em&gt; para que possa ser resgatado quando a lógica do desvio terminar&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sim, estamos falando do desvio com &lt;code&gt;call&lt;/code&gt;, &lt;code&gt;ret&lt;/code&gt;, registradores e pilha.&lt;/p&gt;

&lt;h3&gt;
  
  
  Desvio de fluxo com call
&lt;/h3&gt;

&lt;p&gt;Tendo o exemplo anterior, ao invés de fazer &lt;code&gt;jmp&lt;/code&gt;, vamos utilizar a instrução &lt;code&gt;call&lt;/code&gt; que faz o desvio para outra rotina:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;  &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;------&lt;/span&gt; &lt;span class="nx"&gt;chamada&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;rotina&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Além disso, a última linha da rotina &lt;code&gt;.print&lt;/code&gt; deve "retornar" o fluxo desviado para o ponto anterior.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;greet&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;  &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;------&lt;/span&gt; &lt;span class="nx"&gt;retorno&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;rotina&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Antes de analisarmos com &lt;code&gt;gdb&lt;/code&gt; passo a passo, precisamos entender um aspecto importante dos programas no sistema operacional.&lt;/p&gt;

&lt;p&gt;Quando um programa é executado, ele é definido em uma estrutura chamada &lt;strong&gt;processo&lt;/strong&gt; (já falamos disto no artigo anterior). Todo processo carrega o layout de memória definido no binário do programa, conforme vimos anteriormente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;text -&amp;gt; data -&amp;gt; bss
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nos endereços mais &lt;em&gt;altos&lt;/em&gt; da memória virtual do processo (programa em execução), o sistema operacional também define uma outra estrutura de dados, chamada &lt;strong&gt;stack&lt;/strong&gt;, que tem um formato de pilha (LIFO, Last In, First Out).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;text -&amp;gt; data -&amp;gt; bss ---------&amp;gt; &amp;lt;-------- stack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz7lyluh9a4hqkzl3yo7s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz7lyluh9a4hqkzl3yo7s.png" alt="layout de memória com stack" width="610" height="880"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A stack fica nos endereços mais altos e carrega informações como argumentos do programa, lista de variáveis de ambiente definidas no &lt;em&gt;shell&lt;/em&gt;, argumentos para funções entre qualquer informação pertinente para o programa. Stack sempre cresce &lt;em&gt;para baixo&lt;/em&gt; em direção aos endereços menores.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;rsp&lt;/strong&gt;&lt;br&gt;
Em um programa Assembly x86, é preciso armazenar o ponteiro atual do topo da stack, e esta informação fica no registrador RSP, ou &lt;em&gt;stack pointer&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;rip&lt;/strong&gt;&lt;br&gt;
Já o ponteiro da instrução atual fica no registrador RIP, ou &lt;em&gt;instruction pointer&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Com estes dois registradores conseguimos demonstrar o uso de call e ret para desvio de fluxo. Voltando ao programa:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;global&lt;/span&gt; &lt;span class="nx"&gt;_start&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"Hi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0xA&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;
&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;     &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;--------&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;desvio&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;fluxo&lt;/span&gt;

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;aqui&lt;/span&gt; &lt;span class="nx"&gt;neste&lt;/span&gt; &lt;span class="nx"&gt;ponto&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;continua&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;execu&lt;/span&gt;&lt;span class="err"&gt;çã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;normal&lt;/span&gt; &lt;span class="nx"&gt;em&lt;/span&gt; &lt;span class="nx"&gt;dire&lt;/span&gt;&lt;span class="err"&gt;çã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;ao&lt;/span&gt; &lt;span class="nx"&gt;exit&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;terminar&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;programa&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;greet&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;            &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;----------&lt;/span&gt; &lt;span class="nx"&gt;retorno&lt;/span&gt; &lt;span class="nx"&gt;ao&lt;/span&gt; &lt;span class="nx"&gt;ponto&lt;/span&gt; &lt;span class="nx"&gt;anterior&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E agora demonstrando com &lt;code&gt;gdb&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;gdb greeting

&lt;span class="c"&gt;# Breakpoint em _start, início do programa&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;break &lt;/span&gt;_start_
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; run

&lt;span class="c"&gt;# RIP apontando para 0x401000 (_start), o entry point do programa&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; info register &lt;span class="nv"&gt;$rip&lt;/span&gt;
rip            0x401000            0x401000 &amp;lt;_start&amp;gt;

&lt;span class="c"&gt;# RSP apontando para um endereço de memória&lt;/span&gt;
&lt;span class="c"&gt;# Se formos examinar com x $rsp, temos&lt;/span&gt;
&lt;span class="c"&gt;# 0x7fffffffe450: 0x00000001, que é a quantidade de argumentos&lt;/span&gt;
&lt;span class="c"&gt;# passados, no caso 1 representa apenas o nome do programa, ou seja&lt;/span&gt;
&lt;span class="c"&gt;# não há argumentos na linha de comando&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; i r &lt;span class="nv"&gt;$rsp&lt;/span&gt;
rsp            0x7fffffffe450      0x7fffffffe450
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Até aqui okay, agora vamos andar um &lt;code&gt;step&lt;/code&gt; para que o desvio de &lt;code&gt;call&lt;/code&gt; seja avaliado e analisar o RIP:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; step
18              mov rdi, STDOUT

&lt;span class="c"&gt;# O RIP andou conforme esperado&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; i r &lt;span class="nv"&gt;$rip&lt;/span&gt;
rip            0x401011            0x401011 &amp;lt;_start.print&amp;gt;

&lt;span class="c"&gt;# RIP apontando para 0x000001bf, que é BF 01 00 00 &lt;/span&gt;
&lt;span class="c"&gt;# Lembra? é o opcode pra MOV RDI, 1&lt;/span&gt;
&lt;span class="c"&gt;# Exatamente onde paramos&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &lt;span class="nv"&gt;$rip&lt;/span&gt;
0x401011 &amp;lt;_start.print&amp;gt;:        0x000001bf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E a stack (RSP) como ficou?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# A pilha andou alguns bytes (no caso foi feito um "push", o que a fez crescer para endereços de memórias menores)&lt;/span&gt;
&lt;span class="c"&gt;# Lembra? Pilha "cresce pra baixo" na memória&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; i r rsp
rsp            0x7fffffffe448      0x7fffffffe448

&lt;span class="c"&gt;# Opaaa, o que temos aqui? 0x00401005&lt;/span&gt;
&lt;span class="c"&gt;# É alguma pista...&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &lt;span class="nv"&gt;$rsp&lt;/span&gt;
0x7fffffffe448: 0x00401005

&lt;span class="c"&gt;# Examinando o ponteiro do início do programa...&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x _start
0x401000 &amp;lt;_start&amp;gt;:      0x00000ce8

&lt;span class="c"&gt;# Se andarmos alguns bytes, &lt;/span&gt;
&lt;span class="c"&gt;# temos exatamente o endereço da label .exit, 0x401005&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x _start + 5
0x401005 &amp;lt;_start.exit&amp;gt;: 0x000000bf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se você prestou atenção nos comentários do snippet acima...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;É muito importante prestar atenção em todos os comentários, se não estiver fazendo isso, volte o artigo do início e tente acompanhar &lt;em&gt;no terminal&lt;/em&gt;, é extremamente importante para entender os conceitos&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;...se prestarmos a devida atenção, este é o endereço que tá no topo da pilha agora, que foi adicionado pela instrução &lt;code&gt;call&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ok Leandro, mas como fazemos então para voltar ao ponto anterior?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Calma, jovem. Estamos parados no início da rotina &lt;code&gt;.print&lt;/code&gt;. Vamos continuar a depuração com &lt;code&gt;gdb&lt;/code&gt; até parar em &lt;code&gt;ret&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; next
19              mov rsi, greet
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; next
20              mov rdx, 3
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; next
21              mov rax, SYS_write
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; next
22              syscall
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; next
Hi
_start.print &lt;span class="o"&gt;()&lt;/span&gt; at greeting.asm:23
23              ret
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nice, antes de avaliar a instrução &lt;code&gt;ret&lt;/code&gt;, podemos ver que RIP andou mas RSP continua na mesma, com o endereço da próxima instrução antes do desvio:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# RIP aponta para a instrução da linha "ret"&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &lt;span class="nv"&gt;$rip&lt;/span&gt;
0x40102c &amp;lt;_start.print+27&amp;gt;:     0x000000c3

&lt;span class="c"&gt;# RSP aponta para o endereço de memória que está a instrução .exit, que&lt;/span&gt;
&lt;span class="c"&gt;# vem a seguir ao desvio feito com "call" lá em cima&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &lt;span class="nv"&gt;$rsp&lt;/span&gt;
0x7fffffffe448: 0x00401005
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vamos andar com &lt;code&gt;ret&lt;/code&gt; e....&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# RIP agora aponta para 0x401005, que é a instrução .exit&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &lt;span class="nv"&gt;$rip&lt;/span&gt;
0x401005 &amp;lt;_start.exit&amp;gt;: 0x000000bf

&lt;span class="c"&gt;# Foi feito "pop" em RSP e agora este aponta para o topo da pilha&lt;/span&gt;
&lt;span class="c"&gt;# com o valor exato quando estava no início do programa&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &lt;span class="nv"&gt;$rsp&lt;/span&gt;
0x7fffffffe450: 0x00000001
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;OMG!! Acabamos de demonstrar manipulação de registradores e pilhas&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Brincando com pilhas
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Pilhas é divertido.&lt;/em&gt; &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Mas prefiro filas, gosto de tratar as coisas de modo ordenado. Quem chega primeiro precisa ser atendido primeiro kkkkkkkk&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Mas com pilhas não é assim. Quem entra por último sai primeiro. &lt;/p&gt;

&lt;p&gt;Com base nisto, como podemos manipular a stack do programa? Vamos alterar um pouco o código adicionando o ponteiro de &lt;code&gt;greet&lt;/code&gt; na stack:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;global&lt;/span&gt; &lt;span class="nx"&gt;_start&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"Hi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0xA&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;
&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;push&lt;/span&gt; &lt;span class="nx"&gt;greet&lt;/span&gt;    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;----&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;adiciona&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;ponteiro&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;greet&lt;/span&gt; &lt;span class="nx"&gt;na&lt;/span&gt; &lt;span class="nx"&gt;stack&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;greet&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No &lt;code&gt;gdb&lt;/code&gt;, vamos colocar um breakpoint na linha da chamada &lt;code&gt;call&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Breakpoint na linha 13&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; b 13
Breakpoint 1 at 0x401005: file greeting.asm, line 13.

&lt;span class="c"&gt;# Run&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; r

&lt;span class="c"&gt;# Examinando o topo da pilha&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &lt;span class="nv"&gt;$rsp&lt;/span&gt;
0x7fffffffe448: 0x00402000

&lt;span class="c"&gt;# Examinando o endereço de memória que tá no topo da pilha&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x 0x00402000
0x402000 &amp;lt;greet&amp;gt;:       0x2c0a6948
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Cool&lt;/em&gt;, temos &lt;code&gt;0x48 0x69 0x0A&lt;/code&gt; (little-endian), exatamente a string "Hi" seguida de uma quebra de linha. Com esta rica informação, ao invés da rotina &lt;code&gt;.print&lt;/code&gt; passar pro registrador RSI o ponteiro de &lt;code&gt;greet&lt;/code&gt;, porque não passar o ponteiro do topo da pilha?&lt;/p&gt;

&lt;p&gt;Algo nessa linha:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;ao&lt;/span&gt; &lt;span class="nx"&gt;inv&lt;/span&gt;&lt;span class="err"&gt;é&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="nx"&gt;disso&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;atual&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;greet&lt;/span&gt;

&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;que&lt;/span&gt; &lt;span class="nx"&gt;tal&lt;/span&gt; &lt;span class="nx"&gt;mover&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;ponteiro&lt;/span&gt; &lt;span class="nx"&gt;que&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;em&lt;/span&gt; &lt;span class="nx"&gt;rsp&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;topo&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;pilha&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rsp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por enquanto, seguramos esta ideia no bolso. Ainda no &lt;code&gt;gdb&lt;/code&gt;, vamos continuar analisando a pilha depois de entrar na rotina:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; step
_start.print &lt;span class="o"&gt;()&lt;/span&gt; at greeting.asm:19

&lt;span class="c"&gt;# Agora o topo da pilha foi modificado, "call" colocou o endereço de &lt;/span&gt;
&lt;span class="c"&gt;# memória da próxima instrução quando voltar do "ret"&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &lt;span class="nv"&gt;$rsp&lt;/span&gt;
0x7fffffffe440: 0x0040100a

&lt;span class="c"&gt;# O endereço de memória aponta justamente pra próxima instrução quando voltar do "ret", no caso a instrução que tá na label .exit do programa&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x 0x0040100a
0x40100a &amp;lt;_start.exit&amp;gt;: 0x000000bf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mas agora o topo da pilha estraga nossa ideia de fazer &lt;code&gt;mov rsi, rsp&lt;/code&gt;, mas podemos fazer aritmética com ponteiros e mover o conteúdo resultante, e é muito fácil:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Topo da pilha apontando pra instrução guardada pelo "call"&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &lt;span class="nv"&gt;$rsp&lt;/span&gt;
0x7fffffffe440: 0x0040100a

&lt;span class="c"&gt;# Topo da pilha + 8 bytes apontando pro endereço onde tá a string "Hi"&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &lt;span class="nv"&gt;$rsp&lt;/span&gt;+8
0x7fffffffe448: 0x00402000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Nesta arquitetura, a pilha, assim como os registradores, armazenam por padrão até 8 bytes por cada informação&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Então teoricamente, tudo o que precisamos é &lt;code&gt;mov rsi, [rsp + 8]&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note que é preciso usar &lt;code&gt;[rsp + 8]&lt;/code&gt;, com square brackets é uma forma de fazermos aritmética de ponteiros e acessar o valor resultante da operação na memória, no caso o endereço apontando para a string "Hi"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Para finalizar este primeiro exemplo, é muito importante fazermos "pop" da pilha. Todo &lt;code&gt;push&lt;/code&gt; deve ter um &lt;code&gt;pop&lt;/code&gt;, caso contrário podemos gastar a pilha desnecessariamente e talvez chegar a um stack overflow se exagerarmos bastante.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;global&lt;/span&gt; &lt;span class="nx"&gt;_start&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"Hi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0xA&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;
&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;push&lt;/span&gt; &lt;span class="nx"&gt;greet&lt;/span&gt;             &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;----&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;push&lt;/span&gt; &lt;span class="nx"&gt;na&lt;/span&gt; &lt;span class="nx"&gt;pilha&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;
    &lt;span class="nx"&gt;pop&lt;/span&gt; &lt;span class="nx"&gt;rbp&lt;/span&gt;                &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;----&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;pop&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;pilha&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;jogando&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;valor&lt;/span&gt; &lt;span class="nx"&gt;em&lt;/span&gt; &lt;span class="nx"&gt;rbp&lt;/span&gt;
                           &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;note&lt;/span&gt; &lt;span class="nx"&gt;que&lt;/span&gt; &lt;span class="nx"&gt;rbp&lt;/span&gt; &lt;span class="err"&gt;é&lt;/span&gt; &lt;span class="nx"&gt;outro&lt;/span&gt; &lt;span class="nx"&gt;registrador&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="err"&gt;ó&lt;/span&gt;&lt;span class="nx"&gt;sito&lt;/span&gt; &lt;span class="nx"&gt;geral&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;mas&lt;/span&gt; &lt;span class="nx"&gt;que&lt;/span&gt; &lt;span class="err"&gt;é&lt;/span&gt; &lt;span class="nx"&gt;utilizado&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;manter&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;base&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;pilha&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rsp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;     &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;----&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt; &lt;span class="nx"&gt;depois&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;topo&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;pilha&lt;/span&gt; &lt;span class="nx"&gt;est&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt;
                           &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;endere&lt;/span&gt;&lt;span class="err"&gt;ç&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;mem&lt;/span&gt;&lt;span class="err"&gt;ó&lt;/span&gt;&lt;span class="nx"&gt;ria&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Podemos reparar 2 coisas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A rotina &lt;code&gt;.print&lt;/code&gt; está ficando bastante genérica, ou seja ela não sabe o que está na pilha, simplesmente move para o registrador RSI e faz a syscall &lt;code&gt;write&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A rotina  &lt;code&gt;.print&lt;/code&gt; ainda usa o tamanho em bytes como valor fixo, no caso 3 bytes. Deveria ser dinâmico também se quisermos fazer com que esta rotina seja bem genérica&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Colocamos o tamanho também na pilha? &lt;em&gt;Nah&lt;/em&gt;, seria mais interessante ainda se calculássemos dinamicamente o que vem da pilha. Para fazer este cálculo, teríamos que "iterar", em forma de &lt;em&gt;loop&lt;/em&gt;, por cada byte que queremos imprimir, incrementar em um registrador e utilizar isto na syscall.&lt;/p&gt;

&lt;p&gt;Vamos entrar no mundo dos &lt;strong&gt;loops&lt;/strong&gt; e &lt;strong&gt;condicionais&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Calculando tamanho dinamicamente com loop
&lt;/h3&gt;

&lt;p&gt;Combinando labels e jumps, podemos criar um &lt;em&gt;loop&lt;/em&gt; em assembly, como neste pequeno exemplo a seguir:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Um&lt;/span&gt; &lt;span class="nx"&gt;loop&lt;/span&gt; &lt;span class="nx"&gt;infinito&lt;/span&gt; &lt;span class="nx"&gt;sem&lt;/span&gt; &lt;span class="nx"&gt;condi&lt;/span&gt;&lt;span class="err"&gt;çã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;parada&lt;/span&gt;
&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;N&lt;/span&gt;&lt;span class="err"&gt;ã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;fa&lt;/span&gt;&lt;span class="err"&gt;ç&lt;/span&gt;&lt;span class="nx"&gt;am&lt;/span&gt; &lt;span class="nx"&gt;isso&lt;/span&gt;

&lt;span class="nx"&gt;global&lt;/span&gt; &lt;span class="nx"&gt;_start&lt;/span&gt;

&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;loop&lt;/span&gt;
    &lt;span class="nx"&gt;jmp&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;loop&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Entretanto para adicionarmos uma &lt;em&gt;condição de parada&lt;/em&gt; do loop, é necessário utilizar uma instrução de &lt;strong&gt;comparação&lt;/strong&gt; e outra que &lt;strong&gt;muda algum estado&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;No nosso exemplo, vamos introduzir um &lt;em&gt;loop&lt;/em&gt; que calcula o tamanho da string &lt;em&gt;antes de fazer a syscall&lt;/em&gt;. Entendendo a necessidade:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;Pseudo&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;

&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rsp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="nx"&gt;em&lt;/span&gt; &lt;span class="nx"&gt;RSI&lt;/span&gt;     

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt;           &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;--&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;aqui&lt;/span&gt; &lt;span class="nx"&gt;devemos&lt;/span&gt; &lt;span class="nx"&gt;introduzir&lt;/span&gt; &lt;span class="nx"&gt;um&lt;/span&gt; &lt;span class="nx"&gt;loop&lt;/span&gt; &lt;span class="nx"&gt;que&lt;/span&gt; &lt;span class="nx"&gt;vai&lt;/span&gt;
                         &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;modificando&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;valor&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;RDX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lendo&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt;
                         &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;conte&lt;/span&gt;&lt;span class="err"&gt;ú&lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para resolver isto, podemos criar uma &lt;strong&gt;label&lt;/strong&gt; chamada &lt;code&gt;.calculate_size&lt;/code&gt; que contém um &lt;code&gt;jmp&lt;/code&gt; para ela mesma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rsp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;       &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="nx"&gt;em&lt;/span&gt; &lt;span class="nx"&gt;RSI&lt;/span&gt; 
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;               &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;RDX&lt;/span&gt; &lt;span class="nx"&gt;come&lt;/span&gt;&lt;span class="err"&gt;ç&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;em&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calculate_size&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;             &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;label&lt;/span&gt;
    &lt;span class="nx"&gt;jmp&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calculate_size&lt;/span&gt;      &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;jmp&lt;/span&gt; &lt;span class="s2"&gt;"recursivo"&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ao rodarmos o programa, &lt;em&gt;obviamente&lt;/em&gt; caímos em loop infinito. Precisamos definir uma condição de parada, que consiste em:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;mudar o estado de alguma variável condicional&lt;/li&gt;
&lt;li&gt;desviar o fluxo para outra &lt;em&gt;label&lt;/em&gt; quando a condição for verdadeira&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Em Assembly, podemos fazer a mudança de estado utilizando a instrução &lt;code&gt;inc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rsp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;     
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;             &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;RDX&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contador&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;come&lt;/span&gt;&lt;span class="err"&gt;ç&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;em&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calculate_size&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;                &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;incrementa&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;valor&lt;/span&gt; &lt;span class="nx"&gt;que&lt;/span&gt; &lt;span class="nx"&gt;est&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;em&lt;/span&gt; &lt;span class="nx"&gt;RDX&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;linha&lt;/span&gt; &lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;jmp&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calculate_size&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com gdb, verificamos que o valor de RDX está sempre sendo incrementado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Adicionar breakpoint na linha 23 (&amp;lt;&amp;lt;inc rdx&amp;gt;&amp;gt;)&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;break &lt;/span&gt;23
Breakpoint 1 at 0x401021: file live.asm, line 23.

&lt;span class="c"&gt;# Executar o programa, que vai no primeiro breakpoint&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; run
Breakpoint 1, _start.calculate_size &lt;span class="o"&gt;()&lt;/span&gt; at live.asm:23
23              inc rdx

&lt;span class="c"&gt;# Continuar execução até o próximo breakpoint ou fim do programa.&lt;/span&gt;
&lt;span class="c"&gt;# Mas como estamos em loop, o programa vai parar de novo nesta linha&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;

&lt;span class="c"&gt;# Atalho para "info register rdx"&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; i r rdx
rdx            0x1                 1

&lt;span class="c"&gt;# Próxima iteração...&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; i r rdx
rdx            0x2                 2

&lt;span class="c"&gt;# E assim infinitamente pois não temos ainda a segunda premissa da condição de parada, que é a condicional&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; i r rdx
rdx            0x19                25
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como podemos elaborar esta condicional, uma vez que o valor em RDX pode ser infinito, logo ter &lt;em&gt;todas as possibilidades&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;Uma ideia é irmos &lt;strong&gt;consumindo&lt;/strong&gt; byte a byte da string até chegar a &lt;em&gt;zero&lt;/em&gt;. Para isto, podemos definir o fim da string com &lt;code&gt;0x0&lt;/code&gt; e fazer &lt;em&gt;aritmética binária&lt;/em&gt; na própria string, consumindo os bytes até chegar a &lt;code&gt;0x0&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;Eis o exemplo com um pseudo-código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="s2"&gt;"Hi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; 
&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;que&lt;/span&gt; &lt;span class="nx"&gt;em&lt;/span&gt; &lt;span class="nx"&gt;hexabyte&lt;/span&gt; &lt;span class="nx"&gt;fica&lt;/span&gt; &lt;span class="mh"&gt;0x49&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x69&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x00&lt;/span&gt;

&lt;span class="nx"&gt;INCREMENT&lt;/span&gt;
&lt;span class="mh"&gt;0x69&lt;/span&gt; &lt;span class="mh"&gt;0x00&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;consumiu&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="nx"&gt;mais&lt;/span&gt; &lt;span class="err"&gt;à&lt;/span&gt; &lt;span class="nx"&gt;esquerda&lt;/span&gt; &lt;span class="mh"&gt;0x49&lt;/span&gt;

&lt;span class="nx"&gt;INCREMENT&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;consumiu&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="nx"&gt;mais&lt;/span&gt; &lt;span class="err"&gt;à&lt;/span&gt; &lt;span class="nx"&gt;esquerda&lt;/span&gt; &lt;span class="mh"&gt;0x69&lt;/span&gt;
&lt;span class="mh"&gt;0x00&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3v83k677xw88fg49dn86.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3v83k677xw88fg49dn86.png" alt="increment em endereço de memória" width="800" height="946"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Nossa Leandro, que fantástico! Podemos então fazer &lt;code&gt;inc&lt;/code&gt; em um registrador que contém a string, nesse caso o próprio RSI?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Isso mesmo!&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="p"&gt;.....&lt;/span&gt;
&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"Hi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0xA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;      &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;--&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;adicionamos&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="s2"&gt;"zero"&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;identificar&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; 
                            &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;fim&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;

&lt;span class="p"&gt;.....&lt;/span&gt;

&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rsp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;     
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calculate_size&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;                 &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;incrementa&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;valor&lt;/span&gt; &lt;span class="nx"&gt;inteiro&lt;/span&gt; &lt;span class="nx"&gt;em&lt;/span&gt; &lt;span class="nx"&gt;RDX&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contador&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;                 &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;--&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;al&lt;/span&gt;&lt;span class="err"&gt;é&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;incrementar&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;RDX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;incrementamos&lt;/span&gt;
                            &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;tamb&lt;/span&gt;&lt;span class="err"&gt;é&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;RSI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;que&lt;/span&gt; &lt;span class="nx"&gt;cont&lt;/span&gt;&lt;span class="err"&gt;é&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;endere&lt;/span&gt;&lt;span class="err"&gt;ç&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt;
                            &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;mem&lt;/span&gt;&lt;span class="err"&gt;ó&lt;/span&gt;&lt;span class="nx"&gt;ria&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;Aritm&lt;/span&gt;&lt;span class="err"&gt;é&lt;/span&gt;&lt;span class="nx"&gt;tica&lt;/span&gt; &lt;span class="nx"&gt;em&lt;/span&gt; &lt;span class="nx"&gt;hexabytes&lt;/span&gt;
                            &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;vai&lt;/span&gt; &lt;span class="nx"&gt;fazer&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;efeito&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="nx"&gt;consumir&lt;/span&gt; &lt;span class="nx"&gt;os&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt; &lt;span class="nx"&gt;at&lt;/span&gt;&lt;span class="err"&gt;é&lt;/span&gt; &lt;span class="nx"&gt;zero&lt;/span&gt;
    &lt;span class="nx"&gt;jmp&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calculate_size&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora, com &lt;code&gt;gdb&lt;/code&gt;, vamos verificar o que está acontecendo com nosso programa:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Breakpoint na linha &amp;lt;jmp .calculate_size&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;break &lt;/span&gt;25
Breakpoint 1 at 0x401027: file live.asm, line 25.

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; run

&lt;span class="c"&gt;# Cool, o contador RDX foi incrementado&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; i r rdx
rdx            0x1                 1

&lt;span class="c"&gt;# Em RSI, temos outro endereço de memória.&lt;/span&gt;
&lt;span class="c"&gt;# Anteriormente era o início da string, 0x402000, mas agora está&lt;/span&gt;
&lt;span class="c"&gt;# apontando para 0x402001&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; i r rsi
rsi            0x402001            4202497

&lt;span class="c"&gt;# Wow! Temos os bytes da string "i", seguido de "\n", e depois o 0x00&lt;/span&gt;
&lt;span class="c"&gt;# Parece que o inc RSI funcionou como esperávamos?&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt;x /4xb 0x402001
0x402001:       0x69    0x0a    0x00    0x2c

&lt;span class="c"&gt;# A vida continua...&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;

&lt;span class="c"&gt;# Caminho mais curto&lt;/span&gt;
&lt;span class="c"&gt;# E parece que RSI andou mais ainda, agora apontando para o byte "\n"&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &lt;span class="nv"&gt;$rsi&lt;/span&gt;
0x402002:       0x0a

&lt;span class="c"&gt;# A vida continua...&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;

&lt;span class="c"&gt;# O nosso grande momento! Agora RSI aponta para 0x00&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &lt;span class="nv"&gt;$rsi&lt;/span&gt;
0x402003:       0x00
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tudo o que precisamos fazer, neste momento, é comparar &lt;strong&gt;o valor que está em RSI&lt;/strong&gt; com &lt;em&gt;zero&lt;/em&gt;. Se chegou a zero, significa que podemos &lt;em&gt;parar o loop&lt;/em&gt;. Vamos verificar o que está no contador RDX (esperamos que seja 3):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; i r rdx
rdx            0x3                 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Yay! Que grande momento!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Mas como verificar em Assembly se chegou ou não no valor? Existe "IF" e "ELSE" em Assembly?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hell no!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Não. Não tem "IF" e "ELSE" em Assembly.&lt;/p&gt;

&lt;p&gt;Uma possível solução seria:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;utilizar uma instrução que compare o valor de um registrador ou em algum endereço de memória com &lt;strong&gt;qualquer outro valor&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;esta instrução iria guardar o resultado da comparação em outro registrador "especial"&lt;/li&gt;
&lt;li&gt;utilizar outra instrução para fazer &lt;em&gt;desvio do fluxo&lt;/em&gt; de acordo com o valor que estive neste registrador especial&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sim, é aí que entramos no tal do registrador &lt;strong&gt;RFLAGS&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  RFLAGS
&lt;/h3&gt;

&lt;p&gt;O registrador de &lt;em&gt;flags&lt;/em&gt; é um registrador de status que mantém sempre o estado atual da CPU, neste caso estamos referindo a uma CPU x86_64, pelo que chamamos este registrador de &lt;strong&gt;RFLAGS&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Este registrador guarda &lt;em&gt;opcodes condicionais&lt;/em&gt;, que são resultado de diversas operações lógicas e aritméticas que afetam o estado da CPU.&lt;/p&gt;

&lt;p&gt;Voltando ao nosso exemplo, podemos comparar o registrador RSI com o valor 0, e então verificar o que está acontecendo com o registrador &lt;code&gt;eflags&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rsp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;     
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calculate_size&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;
    &lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;
    &lt;span class="nx"&gt;cmp&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mh"&gt;0x00&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;--&lt;/span&gt; &lt;span class="nx"&gt;aqui&lt;/span&gt; &lt;span class="nx"&gt;comparamos&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;em&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;valor&lt;/span&gt; &lt;span class="nx"&gt;que&lt;/span&gt; &lt;span class="nx"&gt;est&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt;
                           &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;em&lt;/span&gt; &lt;span class="nx"&gt;RSI&lt;/span&gt; &lt;span class="nx"&gt;com&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="mh"&gt;0x00&lt;/span&gt;
    &lt;span class="nx"&gt;jmp&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calculate_size&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E com isto podemos conferir com &lt;code&gt;gdb&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Breakpoint na linha &amp;lt;cmp byte [rsi], 0x00&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;break &lt;/span&gt;25

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; run

&lt;span class="c"&gt;# O que temos no primeiro byte de RSI? "i", pois o "H" já foi&lt;/span&gt;
&lt;span class="c"&gt;# consumido no &amp;lt;inc rsi&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x /1xb &lt;span class="nv"&gt;$rsi&lt;/span&gt;
0x402002:       0x69

&lt;span class="c"&gt;# E no eflags?&lt;/span&gt;
&lt;span class="c"&gt;# Nossa, temos o IF que estávamos precisando!!!!!11&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; i r eflags
eflags         0x202               &lt;span class="o"&gt;[&lt;/span&gt; IF &lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Calma jovem, &lt;code&gt;IF&lt;/code&gt; não é o que você está pensando!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;IF&lt;/code&gt; é uma flag chamada &lt;em&gt;interrupt flag&lt;/em&gt;, que está sempre presente no programa em execução. Ela determina se o programa pode ou não sofrer interrupções de hardware. No nosso caso, está sempre habilitada por padrão, e é por este motivo que podemos fazer chamadas de sistema (syscalls).&lt;/p&gt;

&lt;p&gt;Continuando no gdb...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;

&lt;span class="c"&gt;# O que temos em RSI? "\n"&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x /1xb &lt;span class="nv"&gt;$rsi&lt;/span&gt;
0x402002:       0x0a

&lt;span class="c"&gt;# Executar a instrução &amp;lt;cmp byte [rsi], 0x00&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; next

&lt;span class="c"&gt;# Ok, segunda iteração continua na mesma, sem flags adicionais&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; i r eflags
eflags         0x202               &lt;span class="o"&gt;[&lt;/span&gt; IF &lt;span class="o"&gt;]&lt;/span&gt;

&lt;span class="c"&gt;######## Próxima iteração ##########&lt;/span&gt;

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;

&lt;span class="c"&gt;# O que temos em RSI? 0x00, cool.&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x /1xb &lt;span class="nv"&gt;$rsi&lt;/span&gt;
0x402003:       0x00

&lt;span class="c"&gt;# Executar a instrução &amp;lt;cmp byte [rsi], 0x00&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; next

&lt;span class="c"&gt;# Outras flags foram adicionadas ao estado: PF e ZF&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; i r eflags
eflags         0x246               &lt;span class="o"&gt;[&lt;/span&gt; PF ZF IF &lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;PF&lt;/code&gt; é a &lt;em&gt;parity flag&lt;/em&gt;, que é adicionada quando uma operação aritmética em qualquer registrador resulta em paridade ímpar.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Não é do escopo deste artigo entrar em detalhes sobre PF, sugiro a leitura &lt;a href="https://en.wikipedia.org/wiki/Parity_flag" rel="noopener noreferrer"&gt;sobre o assunto&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Já a &lt;code&gt;ZF&lt;/code&gt; é chamada &lt;strong&gt;zero flag&lt;/strong&gt;, adicionada quando uma operação aritmética resulta em zero, que é exatamente o que estamos buscando aqui.&lt;/p&gt;

&lt;p&gt;Agora o que precisamos é desviar o fluxo (lembra do &lt;code&gt;jmp&lt;/code&gt;) quando a &lt;em&gt;flag zero está presente&lt;/em&gt;. Para isto, temos a disposição diversas instruções de jump baseadas em flags:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;jz (jump if zero)&lt;/li&gt;
&lt;li&gt;jnz(jump if not zero)&lt;/li&gt;
&lt;li&gt;je (jump if equal)&lt;/li&gt;
&lt;li&gt;jne (jump if not equal)&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Isto pra mencionar apenas algumas, existem muitas outras que podem ser consultadas &lt;a href="https://en.wikibooks.org/wiki/X86_Assembly/Control_Flow" rel="noopener noreferrer"&gt;aqui&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Com isto, a instrução que precisamos é a &lt;code&gt;jz&lt;/code&gt;, que verifica se a flag &lt;code&gt;ZF&lt;/code&gt; está presente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rsp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;     
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calculate_size&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;
    &lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;
    &lt;span class="nx"&gt;cmp&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mh"&gt;0x00&lt;/span&gt;     &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;--&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;compara&lt;/span&gt; &lt;span class="nx"&gt;RSI&lt;/span&gt; &lt;span class="nx"&gt;com&lt;/span&gt; &lt;span class="mh"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;Adiciona&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;flag&lt;/span&gt; &lt;span class="nx"&gt;ZF&lt;/span&gt;                                  &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;quando&lt;/span&gt; &lt;span class="nx"&gt;chegar&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;zero&lt;/span&gt;
    &lt;span class="nx"&gt;jz&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt;                 &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;--&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;desvia&lt;/span&gt; &lt;span class="nx"&gt;fluxo&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;label&lt;/span&gt; &lt;span class="s2"&gt;".done"&lt;/span&gt; &lt;span class="nx"&gt;caso&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;
                             &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;flag&lt;/span&gt; &lt;span class="nx"&gt;ZF&lt;/span&gt; &lt;span class="nx"&gt;esteja&lt;/span&gt; &lt;span class="nx"&gt;presente&lt;/span&gt;
    &lt;span class="nx"&gt;jmp&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calculate_size&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com &lt;code&gt;gdb&lt;/code&gt;, colocamos o breakpoint na linha &lt;code&gt;mov rdi, STDOUT&lt;/code&gt; que é depois do loop. Caso o programa fique parado nesta linha, significa que o loop foi concluído com sucesso e os bytes da string devidamente calculados:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Breakpoint na linha &amp;lt;mov rdi, STDOUT&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;break &lt;/span&gt;29

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; run

&lt;span class="c"&gt;# Olha o que temos aqui&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; i r rdx rsi
rdx            0x3                 3
rsi            0x402003            4202499

&lt;span class="c"&gt;# E se formos examinar a string (com x/s) em RSI, temos isto:&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x/s &lt;span class="nv"&gt;$rsi&lt;/span&gt;
0x402003:       &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Em RDX, temos o contador, que está em 3, que é a quantidade de bytes que será passada como terceiro argumento da syscall write. Okay, aqui ficou tudo certo.&lt;/li&gt;
&lt;li&gt;Em RSI, temos &lt;code&gt;0x402003&lt;/code&gt;, e o valor está vazio, ou &lt;code&gt;0x00&lt;/code&gt;. Isto é um problema&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O problema reside no fato de que RSI precisa ter o ponteiro para a string em si, e as operações de &lt;code&gt;inc rsi&lt;/code&gt; &lt;strong&gt;modificaram o registrador&lt;/strong&gt;, pelo que não queremos que isto aconteça.&lt;/p&gt;

&lt;p&gt;Podemos então inicialmente mover o valor que está em RSI para outro registrador temporário, que pode ser um daqueles registradores de &lt;em&gt;rascunho&lt;/em&gt;, chamados de &lt;em&gt;draft registers&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rsp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;     
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;          &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;aqui&lt;/span&gt; &lt;span class="nx"&gt;preservamos&lt;/span&gt; &lt;span class="nx"&gt;RSI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;movendo&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;valor&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;R9&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calculate_size&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;
    &lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;r9&lt;/span&gt;               &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;incrementar&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;valor&lt;/span&gt; &lt;span class="nx"&gt;em&lt;/span&gt; &lt;span class="nx"&gt;R9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;preservando&lt;/span&gt; &lt;span class="nx"&gt;assim&lt;/span&gt; &lt;span class="nx"&gt;RSI&lt;/span&gt;
    &lt;span class="nx"&gt;cmp&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;r9&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mh"&gt;0x00&lt;/span&gt;  &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;comparar&lt;/span&gt; &lt;span class="mh"&gt;0x00&lt;/span&gt; &lt;span class="nx"&gt;com&lt;/span&gt; &lt;span class="nx"&gt;R9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="err"&gt;ã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;mais&lt;/span&gt; &lt;span class="nx"&gt;RSI&lt;/span&gt;
    &lt;span class="nx"&gt;jz&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt;
    &lt;span class="nx"&gt;jmp&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calculate_size&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt;       
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;              &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;no&lt;/span&gt; &lt;span class="nx"&gt;momento&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;syscall&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;RSI&lt;/span&gt; &lt;span class="nx"&gt;est&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;intacto&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;contendo&lt;/span&gt;
                         &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;ponteiro&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;endere&lt;/span&gt;&lt;span class="err"&gt;ç&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;mem&lt;/span&gt;&lt;span class="err"&gt;ó&lt;/span&gt;&lt;span class="nx"&gt;ria&lt;/span&gt; &lt;span class="nx"&gt;onde&lt;/span&gt; &lt;span class="nx"&gt;est&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt;
                         &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;localizada&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;nossa&lt;/span&gt; &lt;span class="nx"&gt;querid&lt;/span&gt;&lt;span class="err"&gt;í&lt;/span&gt;&lt;span class="nx"&gt;ssima&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="s2"&gt;"Hi"&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após estas alterações, vamos executar o programa completo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./greeting
Hi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Que dia maravilhoso!&lt;/em&gt; Nosso programa imprime a string "Hi" calculando dinamicamente o tamanho dos bytes da string!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Entretanto, queremos implementar a proposta inicial, não é, Leandro? O programa não tem que ler o nome da linha de comando e imprimir "Hi, Leandro"?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Botando mais pilha no negócio
&lt;/h3&gt;

&lt;p&gt;Nosso objetivo é chamar &lt;code&gt;./greeting&lt;/code&gt; com argumento e assim o programa deve imprimir &lt;code&gt;Hi,&lt;/code&gt; com o argumento enviado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Objetivo, isto ainda não funciona&lt;/span&gt;
./greeting Leandro
Hi, Leandro
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se pensarmos um pouco, podemos inferir que qualquer argumento pode ser armazenado na &lt;em&gt;stack&lt;/em&gt; do processo, que é quando o programa está em execução.&lt;/p&gt;

&lt;p&gt;Com &lt;code&gt;gdb&lt;/code&gt;, podemos confirmar isto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Breakpoint na primeira linha do programa, depois do _start&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;break &lt;/span&gt;12

&lt;span class="c"&gt;# Executa o programa com o argumento "Leandro"&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; run Leandro

&lt;span class="c"&gt;# Onde estará Leandro? Na pilha? (rsp)&lt;/span&gt;
&lt;span class="c"&gt;#      -&amp;gt; x de examine&lt;/span&gt;
&lt;span class="c"&gt;#      -&amp;gt; /8xb os primeiros 8 hexa bytes&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x /8xb &lt;span class="nv"&gt;$rsp&lt;/span&gt;
0x7fffffffe450: 0x02    0x00    0x00    0x00    0x00    0x00    0x00    0x00
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mas o quê significa esse número 2? Vamos examinar a stack e a ordem das informações contidas nela.&lt;/p&gt;

&lt;p&gt;Voltando ao &lt;code&gt;gdb&lt;/code&gt;, e se lermos os próximos 8 bytes na stack?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x /8xb &lt;span class="nv"&gt;$rsp&lt;/span&gt; + 8
0x7fffffffe458: 0xb1    0xe6    0xff    0xff    0xff    0x7f    0x00    0x00
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Lembrando que os bytes são escritos na stack em formato little-endian, ou seja estão invertidos&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Com isto, temos um hexadecimal &lt;code&gt;0x7fffffffe6b1&lt;/code&gt;. Parece um endereço de memória, não?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Examinando o endereço de memória no formato de string (/s)&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x /s 0x7fffffffe6b1
0x7fffffffe6b1: &lt;span class="s2"&gt;"/Users/..../code/asm-x64/live"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wow, temos o primeiro argumento, também chamado de &lt;em&gt;ARG0&lt;/em&gt; que é o nome do programa com o caminho absoluto no sistema operacional.&lt;/p&gt;

&lt;p&gt;Andando mais 8 bytes...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Endereço de memória...&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x /8xb &lt;span class="nv"&gt;$rsp&lt;/span&gt; + 16
0x7fffffffe460: 0xdf    0xe6    0xff    0xff    0xff    0x7f    0x00    0x00

&lt;span class="c"&gt;# Examinando o valor que está no endereço&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x /s 0x7fffffffe6df
0x7fffffffe6df: &lt;span class="s2"&gt;"Leandro"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Yay!&lt;/em&gt; Temos o nosso argumento, armazenado na stack. É o primeiro argumento, também chamado de &lt;em&gt;ARG1&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Se continuarmos andando na stack de 8 em 8 bytes, vamos passar por todos os argumentos (no nosso caso não há mais), e a seguir vamos chegar no vetor ambiente, que contém todas as variáveis de ambiente contidas no shell que está executando o nosso programa&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Com isto, sabemos que o primeiro argumento está localizado em &lt;code&gt;rsp + 16&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;rsp&lt;/code&gt;: quantidade de argumentos&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rsp + 8&lt;/code&gt;: ARG0, nome do programa&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rsp + 16&lt;/code&gt;: ARG1, primeiro argumento (se existir)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rsp + 24&lt;/code&gt;: ARG2, segundo argumento (se existir)&lt;/li&gt;
&lt;li&gt;e assim sucessivamente...até chegar no vetor de variáveis de ambiente (vetor ambiente)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzs0kmzgwigotv9drklh9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzs0kmzgwigotv9drklh9.png" alt="layout de memória com stack" width="800" height="607"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sabendo que nossa &lt;em&gt;sub-rotina&lt;/em&gt; &lt;code&gt;.print&lt;/code&gt; já recebe uma string da stack e calcula dinamicamente o tamanho da string que foi passada, podemos passar pro topo da stack o nosso argumento (que por acaso também está na stack), e em seguida chamada a rotina &lt;code&gt;.print&lt;/code&gt; novamente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"Hi, "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;push&lt;/span&gt; &lt;span class="nx"&gt;greet&lt;/span&gt;      
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;     
    &lt;span class="nx"&gt;pop&lt;/span&gt; &lt;span class="nx"&gt;rbp&lt;/span&gt;     

    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;aqui&lt;/span&gt; &lt;span class="nx"&gt;fazemos&lt;/span&gt; &lt;span class="nx"&gt;push&lt;/span&gt; &lt;span class="nx"&gt;pro&lt;/span&gt; &lt;span class="nx"&gt;topo&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;stack&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;valor&lt;/span&gt; &lt;span class="nx"&gt;que&lt;/span&gt; &lt;span class="nx"&gt;est&lt;/span&gt;&lt;span class="err"&gt;á&lt;/span&gt; &lt;span class="nx"&gt;em&lt;/span&gt; &lt;span class="nx"&gt;RSP&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ARG1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;utilizamos&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;tipo&lt;/span&gt; &lt;span class="s2"&gt;"qword"&lt;/span&gt; &lt;span class="nx"&gt;que&lt;/span&gt; &lt;span class="nx"&gt;significa&lt;/span&gt; &lt;span class="s2"&gt;"quadword"&lt;/span&gt;
    &lt;span class="nx"&gt;push&lt;/span&gt; &lt;span class="nx"&gt;qword&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rsp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;
    &lt;span class="nx"&gt;pop&lt;/span&gt; &lt;span class="nx"&gt;rbp&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O quê significa &lt;strong&gt;quadword&lt;/strong&gt;? Em assembly podemos definir &lt;em&gt;tipos de bytes&lt;/em&gt;, que basicamente são grupos de bytes, podendo ou não caber em um registrador ou stack dependendo da arquitetura da CPU.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;byte&lt;/strong&gt;: especifica 1 byte (8-bit)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;word&lt;/strong&gt;: 2 bytes (16-bit)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;dword&lt;/strong&gt;: 4 bytes (32-bit)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;qword&lt;/strong&gt;: 8 bytes (64-bit)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;tbyte&lt;/strong&gt;: 10 bytes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Na arquitetura x86_64, precisamos especificar que o tipo de byte adicionado na stack, quando não vier de um registrador mas sim de um lugar arbitrário na memória ou stack, tem um determinado &lt;em&gt;tamanho&lt;/em&gt; em bytes.&lt;/p&gt;

&lt;p&gt;Neste caso, estamos utilizando &lt;em&gt;qword&lt;/em&gt; que é justamente 8 bytes (ou 64-bit) que representa a arquitetura em questão.&lt;/p&gt;

&lt;p&gt;Precisamos adicionar mais um caracter, que é o &lt;em&gt;newline&lt;/em&gt;, ou &lt;code&gt;\n&lt;/code&gt;, no fim da mensagem. Para isto, podemos definir um dado inicializado e chamar a rotina &lt;code&gt;.print&lt;/code&gt; , que já está bem "crescidinha", não?&lt;/p&gt;

&lt;p&gt;Programa completo, com comentários:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;global&lt;/span&gt; &lt;span class="nx"&gt;_start&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"Hi, "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="nl"&gt;newline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="mh"&gt;0xA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;
&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;push&lt;/span&gt; &lt;span class="nx"&gt;greet&lt;/span&gt;             &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;adiciona&lt;/span&gt; &lt;span class="s2"&gt;"Hi, "&lt;/span&gt; &lt;span class="nx"&gt;na&lt;/span&gt; &lt;span class="nx"&gt;stack&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;print&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;     
    &lt;span class="nx"&gt;pop&lt;/span&gt; &lt;span class="nx"&gt;rbp&lt;/span&gt;         

    &lt;span class="nx"&gt;push&lt;/span&gt; &lt;span class="nx"&gt;qword&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rsp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;adiciona&lt;/span&gt; &lt;span class="nx"&gt;ARG1&lt;/span&gt; &lt;span class="nx"&gt;na&lt;/span&gt; &lt;span class="nx"&gt;stack&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;print&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;
    &lt;span class="nx"&gt;pop&lt;/span&gt; &lt;span class="nx"&gt;rbp&lt;/span&gt;

    &lt;span class="nx"&gt;push&lt;/span&gt; &lt;span class="nx"&gt;newline&lt;/span&gt;           &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;adiciona&lt;/span&gt; &lt;span class="nx"&gt;newline&lt;/span&gt; &lt;span class="nx"&gt;na&lt;/span&gt; &lt;span class="nx"&gt;stack&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;print&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;
    &lt;span class="nx"&gt;pop&lt;/span&gt; &lt;span class="nx"&gt;rbp&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;                     &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;label&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="err"&gt;é&lt;/span&gt;&lt;span class="nx"&gt;rmino&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;programa&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;                    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;rotina&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="nx"&gt;print&lt;/span&gt; &lt;span class="nx"&gt;no&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rsp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;     
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calculate_size&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;           &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;loop&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;calcular&lt;/span&gt; &lt;span class="nx"&gt;tamanho&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
    &lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;
    &lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;r9&lt;/span&gt;
    &lt;span class="nx"&gt;cmp&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;r9&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mh"&gt;0x00&lt;/span&gt;
    &lt;span class="nx"&gt;jz&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt;
    &lt;span class="nx"&gt;jmp&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calculate_size&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;                     &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;label&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;finalizar&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;rotina&lt;/span&gt; &lt;span class="nx"&gt;print&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="nx"&gt;retornar&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rodamos o programa e:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./greeting Leandro
Hi, Leandro
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;OMG! Eu não estou acreditando no que estou vendo!!!!!11&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Depurando o programa final com strace
&lt;/h3&gt;

&lt;p&gt;Com &lt;em&gt;strace&lt;/em&gt;, podemos fazer o trace de syscalls do programa final. Olha que maravilha isto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;strace ./greeting Leandro

execve&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"./greeting"&lt;/span&gt;, &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"./greeting"&lt;/span&gt;, &lt;span class="s2"&gt;"Leandro"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;, 0x7ffc30f75368 /&lt;span class="k"&gt;*&lt;/span&gt; 24 vars &lt;span class="k"&gt;*&lt;/span&gt;/&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 0
write&lt;span class="o"&gt;(&lt;/span&gt;1, &lt;span class="s2"&gt;"Hi, "&lt;/span&gt;, 4Hi, &lt;span class="o"&gt;)&lt;/span&gt;                     &lt;span class="o"&gt;=&lt;/span&gt; 4
write&lt;span class="o"&gt;(&lt;/span&gt;1, &lt;span class="s2"&gt;"Leandro"&lt;/span&gt;, 7Leandro&lt;span class="o"&gt;)&lt;/span&gt;                  &lt;span class="o"&gt;=&lt;/span&gt; 7
write&lt;span class="o"&gt;(&lt;/span&gt;1, &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;, 1
&lt;span class="o"&gt;)&lt;/span&gt;                       &lt;span class="o"&gt;=&lt;/span&gt; 1
&lt;span class="nb"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;0&lt;span class="o"&gt;)&lt;/span&gt;                                 &lt;span class="o"&gt;=&lt;/span&gt; ?
+++ exited with 0 +++
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Foram feitas 4 chamadas de sistema, sendo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1 write, "Hi, "&lt;/li&gt;
&lt;li&gt;1 write "Leandro"&lt;/li&gt;
&lt;li&gt;1 write "\n"&lt;/li&gt;
&lt;li&gt;1 exit&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Falando um pouco de registradores
&lt;/h2&gt;

&lt;p&gt;Até o momento, vimos durante este artigo a utilização de alguns registradores que foram muito úteis para o desenvolvimento do programa, dentre eles &lt;em&gt;RSI&lt;/em&gt;, &lt;em&gt;RAX&lt;/em&gt;, &lt;em&gt;RDX&lt;/em&gt;, &lt;em&gt;RSP&lt;/em&gt;, &lt;em&gt;RIP&lt;/em&gt;, &lt;em&gt;RFLAGS&lt;/em&gt; e assim por diante.&lt;/p&gt;

&lt;p&gt;Mas qual o &lt;strong&gt;propósito de cada registrador&lt;/strong&gt;? Posso usar qualquer registrador para qualquer operação, de forma aleatória?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;De forma prática, sim. Mas nem sempre convém.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nada impede que o teu programa coloque qualquer valor em um registrador arbitrário. Por exemplo, com &lt;code&gt;gdb&lt;/code&gt; vamos alterar alguns registradores e ver como o programa se comporta:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Breakpoint &amp;amp; run&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;break &lt;/span&gt;13
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; run Leandro

&lt;span class="c"&gt;# Vamos alterar alguns registradores arbitrários&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nv"&gt;$rax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 42
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nv"&gt;$rdx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 33

&lt;span class="c"&gt;# Confirmando que foram modificados&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; i r rax rdx
rax            0x2a                42
rdx            0x21                33

&lt;span class="c"&gt;# Continuando...&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;continue
&lt;/span&gt;Continuing.
Hi, Leandro
&lt;span class="o"&gt;[&lt;/span&gt;Inferior 1 &lt;span class="o"&gt;(&lt;/span&gt;process 19231&lt;span class="o"&gt;)&lt;/span&gt; exited normally]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Okay, podemos ver que ter mudado estes registradores para &lt;em&gt;qualquer valor&lt;/em&gt; não impactou o programa. No meio do programa, provavelmente eles são sobrescritos novamente e utilizados de acordo com &lt;em&gt;determinada lógica&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Mas e se alterarmos, por exemplo, um registrador como o &lt;code&gt;rip&lt;/code&gt;, que é o &lt;em&gt;ponteiro da próxima instrução&lt;/em&gt;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Breakpoint &amp;amp; run&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;break &lt;/span&gt;13
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; run Leandro

&lt;span class="c"&gt;# Antes de alterar o RIP, podemos ver qual o valor ele carrega,&lt;/span&gt;
&lt;span class="c"&gt;# que é o ponteiro da próxima instrução&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; i r rip
rip            0x401000            0x401000 &amp;lt;_start&amp;gt;

&lt;span class="c"&gt;# Vamos alterar o registrador RIP&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nv"&gt;$rip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 42

&lt;span class="c"&gt;# Confirmando que foi alterando&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; i r rip
rip            0x2a                0x2a

&lt;span class="c"&gt;# Continuando...&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;continue
&lt;/span&gt;Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x000000000000002a &lt;span class="k"&gt;in&lt;/span&gt; ?? &lt;span class="o"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Ouch!&lt;/em&gt; Agora o programa não pôde ser finalizado com sucesso. Confirmamos então que nem sempre convém mudar os registradores sem &lt;em&gt;haver algum critério&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Propósito dos registradores
&lt;/h3&gt;

&lt;p&gt;Os registradores, e falando especificamente da arquitetura x86, seguem um &lt;strong&gt;propósito original&lt;/strong&gt; para o qual foram designados. Mas também podem ser utilizados em convenções de &lt;strong&gt;chamadas de sistema&lt;/strong&gt; tal como vimos na montagem das syscalls &lt;code&gt;write&lt;/code&gt; e &lt;code&gt;exit&lt;/code&gt;, e neste caso a utilização correta importa bastante. &lt;/p&gt;

&lt;p&gt;E além disso, alguns registradores contém dados importantes para a execução do programa, tais como o &lt;code&gt;rip&lt;/code&gt; e &lt;code&gt;eflags&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Propósito original&lt;/li&gt;
&lt;li&gt;Convenções de chamadas&lt;/li&gt;
&lt;li&gt;Funcionamento crítico do programa&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Apesar destas características importantes de uso dos registradores, podem haver situações em que utilizar um registrador de propósito geral é o que faz mais sentido para o programa. Vamos a seguir destacar alguns registradores e seus &lt;em&gt;propósitos originais&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Registradores de propósito geral
&lt;/h3&gt;

&lt;p&gt;Podemos categorizar os registradores de uso geral em 2 partes: manipulação de &lt;em&gt;dados diretos&lt;/em&gt; ou &lt;em&gt;endereços de memória&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dados&lt;/strong&gt;&lt;br&gt;
Registradores podem manipular dados, que chamamos de &lt;em&gt;valor imediato&lt;/em&gt;, e nesta categoria podemos utilizar RAX, RBX, RCX, RDX e os registradores de rascunho que vão de R8 a R15.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RAX&lt;/strong&gt;: operações aritméticas e armazenamento de resultados; também usado para o nome de chamadas de sistema em convenções de chamada (syscalls)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RBX&lt;/strong&gt;: ponteiro de base, utilizado para o endereço de algumas informações na memória&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RCX&lt;/strong&gt;: geralmente usado como contador, para armazenar a quantidade de vezes que uma instrução deve ser executada&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RDX&lt;/strong&gt;: usado para algumas operações de multiplicação e divisão, muito utilizado para armazenar o resto de operações&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;R8 a R15&lt;/strong&gt;: registradores de &lt;em&gt;rascunho&lt;/em&gt; utilizados para propósito geral&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Endereços de memória&lt;/strong&gt;&lt;br&gt;
Registradores também permitem manipular endereços de memória. Nesta categoria temos RSI, RDI, RBP e RSP.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RSI&lt;/strong&gt;: utilizado como um ponteiro de origem em operações de transferências de dados, frequentemente usado em loops para iterar sobre arrays ou buffers de dados&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RDI&lt;/strong&gt;: utilizado como ponteiro de destino em operações de transferências de dados, frequentemente usado junto com RSI&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RBP&lt;/strong&gt;: frequentemente usado como ponteiro base em operações de memória, para referenciar variáveis locais e parâmetros de função na stack&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RSP&lt;/strong&gt;: ponteiro para o topo da pilha (stack) do programa em execução&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Registradores especiais
&lt;/h3&gt;

&lt;p&gt;Vamos destacar apenas 2 dos registradores considerados "especiais":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RFLAGS&lt;/strong&gt;: utilizado para armazenar o estado da CPU, frequentemente modificado por instruções aritméticas e controle de paridade binária&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RIP&lt;/strong&gt;: ponteiro de instrução, que sempre contém o endereço da próxima instrução a ser executada. Por exemplo, a instrução &lt;code&gt;ret&lt;/code&gt; busca o endereço do topo da pilha e modifica o &lt;code&gt;rip&lt;/code&gt; para que o programa continue a partir daquele ponto&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz3ospgiir3a2nv78nm96.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz3ospgiir3a2nv78nm96.png" alt="tipos de registradores" width="800" height="680"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Precisamos sempre utilizar todos os 64 bits?
&lt;/h3&gt;

&lt;p&gt;Sabemos que registradores nesta arquitetura &lt;strong&gt;ocupam 64 bits de memória&lt;/strong&gt;. Mas e quando o dado que estamos manipulando não precisa dos 64 bits? Conseguimos otimizar o uso de memória?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A ideia seria algo do tipo "por favor me dê uma fatia dos 64 bits, não preciso de tudo"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Historicamente, como vimos na parte II desta saga, as CPU's x86 não começaram com 64 bits. Evoluíram de 8 bits, para 16, então 32 até chegar em 64 bits.&lt;/p&gt;

&lt;p&gt;Para manter compatibilidade, os registradores "legados" podem ser utilizados na arquitetura x64, e assim quando não houver necessidade de utilizar todos os bits do registrador, podemos utilizar uma &lt;em&gt;fatia menor&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Por exemplo, o registrador RAX de 64-bits tem o seu equivalente de 32-bits que é o EAX, que &lt;strong&gt;ocupa os 32 bits mais baixos&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;O registrador EAX, por sua vez, tem o equivalente AX de 8-bits. Dentro deste AX, podemos utilizar ainda a parte &lt;strong&gt;maior&lt;/strong&gt; que se chama AH ou a parte &lt;strong&gt;menor&lt;/strong&gt; que se chama AL.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;O "H" em AH vem de "high", e consequentemente "L" de AL significa "low". Óbvio, não? :P&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sendo assim, há situações em que ao invés de:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;  &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="nx"&gt;mas&lt;/span&gt; &lt;span class="nx"&gt;ocupa&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt; &lt;span class="nx"&gt;bits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E sabendo que 42 não ocupa 64 bits, podemos mudar para:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;  &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="nx"&gt;mas&lt;/span&gt; &lt;span class="nx"&gt;ocupa&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="nx"&gt;bytes&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt; &lt;span class="nx"&gt;bits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ou então:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;   &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="nx"&gt;ocupando&lt;/span&gt; &lt;span class="nx"&gt;exatamente&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="nx"&gt;bits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assim o programa final passa a ocupar menos memória em sua totalidade. &lt;/p&gt;

&lt;p&gt;Seguindo esta lógica, podemos aplicar para todos os registradores, trazendo alguns como exemplo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RAX&lt;/strong&gt;: &lt;code&gt;EAX -&amp;gt; AX -&amp;gt; AH -&amp;gt; AL&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RBX&lt;/strong&gt;: &lt;code&gt;EBX -&amp;gt; BX -&amp;gt; BH -&amp;gt; BL&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RDX&lt;/strong&gt;: &lt;code&gt;RDX -&amp;gt; DX -&amp;gt; DH -&amp;gt; DL&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;R8&lt;/strong&gt;: &lt;code&gt;R8W -&amp;gt; R8B&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwtp88ythfnm7yj2rhefw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwtp88ythfnm7yj2rhefw.png" alt="fatias de registradores" width="800" height="172"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E assim por diante.&lt;/p&gt;




&lt;h2&gt;
  
  
  Uma side note sobre stack frames
&lt;/h2&gt;

&lt;p&gt;Depois de publicar o artigo, o &lt;a href="https://twitter.com/rodrigogbranco" rel="noopener noreferrer"&gt;Rodrigo Gonçalves de Branco&lt;/a&gt; decidiu dar um &lt;a href="https://docs.google.com/document/d/10xr0Qm6jatko2dRyQYqXuToXp5DShxl6dhmBnPPUAb4/edit" rel="noopener noreferrer"&gt;feedback ultra detalhado&lt;/a&gt; executando todos os exemplos aqui demonstrados, e um dos insights foi sobre a utilização de stack frames.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Foi um trabalho fenomenal, meus agradecimentos ao Rodrigo&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Voltando ao exemplo dos &lt;strong&gt;argumentos na pilha&lt;/strong&gt;, dentro da rotina &lt;code&gt;_start&lt;/code&gt;, temos a pilha do programa com o seguinte layout:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuaiuvwiltzhlzj5bxner.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuaiuvwiltzhlzj5bxner.png" alt="rsp antes" width="800" height="822"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Quando fazemos a chamada:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="nx"&gt;push&lt;/span&gt; &lt;span class="nx"&gt;greet&lt;/span&gt;    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;adiciona&lt;/span&gt; &lt;span class="s2"&gt;"Hi, "&lt;/span&gt; &lt;span class="nx"&gt;na&lt;/span&gt; &lt;span class="nx"&gt;stack&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;print&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;     
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Estamos basicamente &lt;em&gt;manipulando a pilha original&lt;/em&gt; do programa. O &lt;code&gt;push&lt;/code&gt; vai colocar no topo da pilha (RSP) o endereço de &lt;code&gt;greet&lt;/code&gt;, como demonstrado a seguir no GDB:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Breakpoint no &amp;lt;push greet&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;break &lt;/span&gt;13   

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; run
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; next

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &lt;span class="nv"&gt;$rsp&lt;/span&gt;
0x7fffffffe448: 0x00402000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora a pilha ficou assim:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3tqkty8gtj5olc876qtd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3tqkty8gtj5olc876qtd.png" alt="layout com pilha e data" width="800" height="429"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se fizermos &lt;code&gt;step&lt;/code&gt; no GDB, podemos ver que o RSP foi modificado novamente, desta vez adicionando o endereço da próxima instrução por conta da chamada &lt;code&gt;call&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; step

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &lt;span class="nv"&gt;$rsp&lt;/span&gt;
0x7fffffffe440: 0x0040100a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7kis57u2auas91bcebog.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7kis57u2auas91bcebog.png" alt="layout com data e text" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Isso é o que acontece com a pilha em uma simples chamada de rotina com argumentos!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Bom, sabendo disso, vemos que o argumento que precisamos está em &lt;code&gt;rsp + 8&lt;/code&gt;, exatamente como no nosso programa original. &lt;em&gt;So far, so good&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;O problema é que podemos reparar que o RSP é modificado durante as chamadas de funções no programa. Não temos controle sobre isso.&lt;/p&gt;

&lt;p&gt;E podem acontecer &lt;em&gt;comportamentos inesperados&lt;/em&gt; (bugs?) quando isso ocorre, pelo simples fato de estarmos &lt;strong&gt;apontando dados na pilha&lt;/strong&gt; e eles já estarem em posições que não esperávamos.&lt;/p&gt;

&lt;p&gt;Para mitigar este potencial problema, podemos preservar a &lt;strong&gt;base da pilha&lt;/strong&gt; em algum registrador sempre no início de cada função, desta forma cada rotina/função pode ter sua própria "versão" da pilha sem correr riscos de apontar para o dado errado. &lt;/p&gt;

&lt;p&gt;Esta técnica é chamada de &lt;strong&gt;stack frame&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;E é pra isso que usamos o &lt;strong&gt;registrador RBP&lt;/strong&gt;! No &lt;em&gt;prólogo&lt;/em&gt; de cada rotina, adicionamos o &lt;code&gt;rbp&lt;/code&gt; na pilha e em seguida colocamos o ponteiro de &lt;code&gt;rsp&lt;/code&gt; dentro do registrador &lt;code&gt;rbp&lt;/code&gt;, igualando assim ambos registradores:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;_start&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;push&lt;/span&gt; &lt;span class="nx"&gt;rbp&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rsp&lt;/span&gt;
&lt;span class="p"&gt;....&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsi286ldan8b9swswr9q0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsi286ldan8b9swswr9q0.png" alt="rsp e rbp" width="800" height="922"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Repare que esta técnica consiste em &lt;em&gt;igualar&lt;/em&gt; RSP com RBP, assim pode-se de forma segura manipular o &lt;em&gt;ponteiro em RBP&lt;/em&gt;, pois mesmo RSP sendo modificado pelo programa, RBP continua intacto.&lt;/p&gt;

&lt;p&gt;Continuando com o programa:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;push&lt;/span&gt; &lt;span class="nx"&gt;rbp&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rsp&lt;/span&gt;
&lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="nx"&gt;push&lt;/span&gt; &lt;span class="nx"&gt;greet&lt;/span&gt;
&lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;
&lt;span class="p"&gt;....&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Constatamos no GDB que a stack foi alterada, portanto RSP foi modificado para apontar para o endereço da próxima instrução, ao passo que RBP continua apontando pro valor anterior:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# RBP &lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &lt;span class="nv"&gt;$rbp&lt;/span&gt;
0x7fffffffe448: 0x00000000

&lt;span class="c"&gt;# RSP aponta para o endereço da próxima instrução &lt;/span&gt;
&lt;span class="c"&gt;# antes da chamada da rotina&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &lt;span class="nv"&gt;$rsp&lt;/span&gt;
0x7fffffffe438: 0x0040100e

&lt;span class="c"&gt;# RSP + 8 aponta para o primeiro argumento da rotina&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &lt;span class="nv"&gt;$rsp&lt;/span&gt; + 8
0x7fffffffe440: 0x00402000

&lt;span class="c"&gt;# RSP + 16 aponta para o mesmo valor de RBP (base da pilha),&lt;/span&gt;
&lt;span class="c"&gt;# ou seja, `RBP = RSP + 16` neste caso porque houve um PUSH&lt;/span&gt;
&lt;span class="c"&gt;# explícito do argumento e também outro push feito pelo CALL&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &lt;span class="nv"&gt;$rsp&lt;/span&gt; + 16
0x7fffffffe448: 0x00000000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa3fjvaxlpm4g8c41jnl8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa3fjvaxlpm4g8c41jnl8.png" alt="rbp  = rsp + 16" width="800" height="622"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E modificando a rotina &lt;code&gt;.print&lt;/code&gt; para também ter seu próprio stack frame, como fica a pilha depois de executar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;push&lt;/span&gt; &lt;span class="nx"&gt;rbp&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rsp&lt;/span&gt;
&lt;span class="p"&gt;....&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Analisando com GDB:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &lt;span class="nv"&gt;$rbp&lt;/span&gt;
0x7fffffffe430: 0xffffe448

&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; x &lt;span class="nv"&gt;$rsp&lt;/span&gt;
0x7fffffffe430: 0xffffe448
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;RSP e RBP ficaram igualados novamente, dando uma característica de stack frame, preservando a pilha como podemos ver na imagem a seguir:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foyrhiaqltlra50b8fi2w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foyrhiaqltlra50b8fi2w.png" alt="stack frame" width="782" height="950"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Portanto, o argumento da rotina, ao invés de ser &lt;code&gt;rsp + 8&lt;/code&gt;, passa a ser &lt;code&gt;rbp + 16&lt;/code&gt; por conta da stack frame, ficando da seguinte forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;                  
    &lt;span class="nx"&gt;push&lt;/span&gt; &lt;span class="nx"&gt;rbp&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rsp&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;     
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Uma coisa importante&lt;/em&gt;: ao final de cada rotina, antes do &lt;em&gt;retorno&lt;/em&gt;, devemos fazer &lt;code&gt;pop&lt;/code&gt; do topo da pilha para voltar ao estado original antes do &lt;code&gt;push rbp&lt;/code&gt; feito no início da rotina:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;push&lt;/span&gt; &lt;span class="nx"&gt;rbp&lt;/span&gt;
&lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rsp&lt;/span&gt;
&lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="nx"&gt;pop&lt;/span&gt; &lt;span class="nx"&gt;rbp&lt;/span&gt;
&lt;span class="nx"&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Desta forma, ao fazer o &lt;code&gt;pop rbp&lt;/code&gt;, o que está em RSP é justamente o endereço de retorno antes da chamada da função:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4kbrojascqyspoa4lhjl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4kbrojascqyspoa4lhjl.png" alt="pop do rbp antes do retorno" width="800" height="1005"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ao continuar com o programa, a instrução &lt;code&gt;ret&lt;/code&gt; (já falamos sobre ela anteriormente) faz &lt;em&gt;pop&lt;/em&gt; do topo da pilha (RSP) e continua a execução do programa na próxima instrução:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;_start&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;push&lt;/span&gt; &lt;span class="nx"&gt;rbp&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rsp&lt;/span&gt;     &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;--&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;iguala&lt;/span&gt; &lt;span class="nx"&gt;RSP&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="nx"&gt;RBP&lt;/span&gt;

    &lt;span class="nx"&gt;push&lt;/span&gt; &lt;span class="nx"&gt;greet&lt;/span&gt;       &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;--&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;adiciona&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;greet&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;na&lt;/span&gt; &lt;span class="nx"&gt;pilha&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;      &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;--&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;adiciona&lt;/span&gt; &lt;span class="nx"&gt;ponteiro&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;pr&lt;/span&gt;&lt;span class="err"&gt;ó&lt;/span&gt;&lt;span class="nx"&gt;xima&lt;/span&gt; 
                         &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;instru&lt;/span&gt;&lt;span class="err"&gt;çã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;na&lt;/span&gt; &lt;span class="nx"&gt;pilha&lt;/span&gt;
    &lt;span class="nx"&gt;pop&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;          &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;--&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;faz&lt;/span&gt; &lt;span class="nx"&gt;pop&lt;/span&gt; &lt;span class="nx"&gt;de&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;greet&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;pilha&lt;/span&gt;      

&lt;span class="p"&gt;............&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;                 
    &lt;span class="nx"&gt;push&lt;/span&gt; &lt;span class="nx"&gt;rbp&lt;/span&gt;         
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rsp&lt;/span&gt;     &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;--&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;iguala&lt;/span&gt; &lt;span class="nx"&gt;RSP&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="nx"&gt;RBP&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;     
        &lt;span class="p"&gt;.............&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;
    &lt;span class="nx"&gt;pop&lt;/span&gt; &lt;span class="nx"&gt;rbp&lt;/span&gt;          &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;--&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;remove&lt;/span&gt; &lt;span class="nx"&gt;frame&lt;/span&gt; &lt;span class="nx"&gt;RBP&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;pilha&lt;/span&gt;
    &lt;span class="nx"&gt;ret&lt;/span&gt;              &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;--&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;faz&lt;/span&gt; &lt;span class="nx"&gt;pop&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;pointeiro&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; 
                         &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;pr&lt;/span&gt;&lt;span class="err"&gt;ó&lt;/span&gt;&lt;span class="nx"&gt;xima&lt;/span&gt; &lt;span class="nx"&gt;instru&lt;/span&gt;&lt;span class="err"&gt;çã&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="nx"&gt;atualiza&lt;/span&gt; &lt;span class="nx"&gt;RIP&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnrhswxyhluvlc9yvlyem.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnrhswxyhluvlc9yvlyem.png" alt="layout depois do ret" width="800" height="700"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Quando o fluxo volta para quem chamou a rotina, a próxima instrução deve ser sempre o &lt;code&gt;pop&lt;/code&gt; dos argumentos que entraram na pilha. &lt;/p&gt;

&lt;p&gt;Neste caso no exemplo anterior estamos fazendo &lt;em&gt;pop&lt;/em&gt; do argumento e descartando o valor em RAX com &lt;code&gt;pop rax&lt;/code&gt;, deixando assim a pilha em seu estado anterior à chamada da rotina:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuxp5nup5nzqs19hx3nwb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuxp5nup5nzqs19hx3nwb.png" alt="final" width="800" height="677"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ao fim do programa (rotina &lt;code&gt;_start&lt;/code&gt;), devemos também fazer &lt;code&gt;pop rbp&lt;/code&gt;, assim a pilha volta ao estado original de quando foi iniciado o programa.&lt;/p&gt;

&lt;p&gt;Código completo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight actionscript"&gt;&lt;code&gt;&lt;span class="nx"&gt;global&lt;/span&gt; &lt;span class="nx"&gt;_start&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="nl"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="s2"&gt;"Hi, "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="nl"&gt;newline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="mh"&gt;0xA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;
&lt;span class="nl"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;push&lt;/span&gt; &lt;span class="nx"&gt;rbp&lt;/span&gt;               &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;--&lt;/span&gt; &lt;span class="nx"&gt;cria&lt;/span&gt; &lt;span class="nx"&gt;um&lt;/span&gt; &lt;span class="nx"&gt;stack&lt;/span&gt; &lt;span class="nx"&gt;frame&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rsp&lt;/span&gt;           &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;preservar&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;pilha&lt;/span&gt;

    &lt;span class="nx"&gt;push&lt;/span&gt; &lt;span class="nx"&gt;greet&lt;/span&gt;             &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;adiciona&lt;/span&gt; &lt;span class="s2"&gt;"Hi, "&lt;/span&gt; &lt;span class="nx"&gt;na&lt;/span&gt; &lt;span class="nx"&gt;pilha&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;            &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;chama&lt;/span&gt; &lt;span class="nx"&gt;sub&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;rotina&lt;/span&gt;
    &lt;span class="nx"&gt;pop&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;                &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;remove&lt;/span&gt; &lt;span class="s2"&gt;"Hi, "&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;pilha&lt;/span&gt;

    &lt;span class="nx"&gt;push&lt;/span&gt; &lt;span class="nx"&gt;qword&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;adiciona&lt;/span&gt; &lt;span class="nx"&gt;argumento&lt;/span&gt; &lt;span class="nx"&gt;na&lt;/span&gt; &lt;span class="nx"&gt;pilha&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;            &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;chama&lt;/span&gt; &lt;span class="nx"&gt;sub&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;rotina&lt;/span&gt;
    &lt;span class="nx"&gt;pop&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;                &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;remove&lt;/span&gt; &lt;span class="nx"&gt;argumento&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;pilhha&lt;/span&gt;

    &lt;span class="nx"&gt;push&lt;/span&gt; &lt;span class="nx"&gt;newline&lt;/span&gt;           &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;adiciona&lt;/span&gt; &lt;span class="nx"&gt;newline&lt;/span&gt; &lt;span class="nx"&gt;na&lt;/span&gt; &lt;span class="nx"&gt;pilha&lt;/span&gt;
    &lt;span class="nx"&gt;call&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;            &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;chama&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;subrotina&lt;/span&gt;
    &lt;span class="nx"&gt;pop&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;                &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;remove&lt;/span&gt; &lt;span class="nx"&gt;newline&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;pilha&lt;/span&gt;

    &lt;span class="nx"&gt;pop&lt;/span&gt; &lt;span class="nx"&gt;rbp&lt;/span&gt;                &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;remove&lt;/span&gt; &lt;span class="nx"&gt;RBP&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;pilha&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                               &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;retornando&lt;/span&gt; &lt;span class="nx"&gt;ao&lt;/span&gt; &lt;span class="nx"&gt;estado&lt;/span&gt; &lt;span class="nx"&gt;original&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;               
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_exit&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;                &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;termina&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;programa&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;                   
    &lt;span class="nx"&gt;push&lt;/span&gt; &lt;span class="nx"&gt;rbp&lt;/span&gt;               &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;--&lt;/span&gt; &lt;span class="nx"&gt;cria&lt;/span&gt; &lt;span class="nx"&gt;um&lt;/span&gt; &lt;span class="nx"&gt;stack&lt;/span&gt; &lt;span class="nx"&gt;frame&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rsp&lt;/span&gt;           &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;preservar&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;pilha&lt;/span&gt;

    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rbp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;     
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;r9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rsi&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calculate_size&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;               &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;loop&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;calcular&lt;/span&gt; &lt;span class="nx"&gt;tamanho&lt;/span&gt;
    &lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;rdx&lt;/span&gt;
    &lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="nx"&gt;r9&lt;/span&gt;
    &lt;span class="nx"&gt;cmp&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;r9&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mh"&gt;0x00&lt;/span&gt;
    &lt;span class="nx"&gt;jz&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt;
    &lt;span class="nx"&gt;jmp&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calculate_size&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;                     
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;STDOUT&lt;/span&gt;
    &lt;span class="nx"&gt;mov&lt;/span&gt; &lt;span class="nx"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYS_write&lt;/span&gt;
    &lt;span class="nx"&gt;syscall&lt;/span&gt;

    &lt;span class="nx"&gt;pop&lt;/span&gt; &lt;span class="nx"&gt;rbp&lt;/span&gt;                &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;--&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;remove&lt;/span&gt; &lt;span class="nx"&gt;RBP&lt;/span&gt; &lt;span class="nx"&gt;da&lt;/span&gt; &lt;span class="nx"&gt;pilha&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                               &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;retornando&lt;/span&gt; &lt;span class="nx"&gt;ao&lt;/span&gt; &lt;span class="nx"&gt;estado&lt;/span&gt; &lt;span class="nx"&gt;anterior&lt;/span&gt;

    &lt;span class="nx"&gt;ret&lt;/span&gt;                    &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;--&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;retorna&lt;/span&gt; &lt;span class="nx"&gt;fluxo&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt;
                               &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;estado&lt;/span&gt; &lt;span class="nx"&gt;anterior&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4zqxli9xe88yxloe21ht.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4zqxli9xe88yxloe21ht.png" alt="voltando ao estado original da pilha" width="574" height="483"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;É isto. Esta seção foi apenas uma demonstração de como utilizar boas práticas de manipulação da pilha quando utilizamos argumentos em funções, através da técnica de &lt;em&gt;criar um frame&lt;/em&gt; como &lt;strong&gt;base da pilha&lt;/strong&gt; com o registrador RBP.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;É isto, pessoal. Esta parte da saga foi bastante densa. Passamos pela criação de um programa simples em Assembly, ao passo em que íamos depurando o programa com ferramentas como &lt;em&gt;strace&lt;/em&gt;, &lt;em&gt;size&lt;/em&gt; e &lt;strong&gt;muito gdb&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Também aprendemos sobre labels, tipos de registradores, desvio de fluxo com jmp, call, ret, &lt;strong&gt;muita stack&lt;/strong&gt;, depurando tudo e mais um pouco, loops, FLAGS e aritmética de ponteiro.&lt;/p&gt;

&lt;p&gt;Apesar de ter sido muito denso, os tópicos aqui abordados servirão de base para entendermos o próximo artigo que já começa pesado com syscalls de rede, para iniciarmos o nosso tão esperado web server.&lt;/p&gt;

&lt;p&gt;Nos vemos no próximo artigo!&lt;/p&gt;




&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;p&gt;&lt;br&gt;
Mnemonics&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Mnemonic" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Mnemonic&lt;/a&gt;&lt;br&gt;
Comparison of Assemblers&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Comparison_of_assemblers" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Comparison_of_assemblers&lt;/a&gt;&lt;br&gt;
Linker (computing)&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Linker_(computing)" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Linker_(computing)&lt;/a&gt;&lt;br&gt;
Assembly x86 tutorial&lt;br&gt;
&lt;a href="https://www.tutorialspoint.com/assembly_programming/index.htm" rel="noopener noreferrer"&gt;https://www.tutorialspoint.com/assembly_programming/index.htm&lt;/a&gt;&lt;br&gt;
Data segment&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Data_segment" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Data_segment&lt;/a&gt;&lt;br&gt;
FLAGS register&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/FLAGS_register" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/FLAGS_register&lt;/a&gt;&lt;br&gt;
Debugging with GDB&lt;br&gt;
&lt;a href="https://ncona.com/2019/12/debugging-assembly-with-gdb/" rel="noopener noreferrer"&gt;https://ncona.com/2019/12/debugging-assembly-with-gdb/&lt;/a&gt;&lt;br&gt;
GDB command reference&lt;br&gt;
&lt;a href="https://visualgdb.com/gdbreference/commands/" rel="noopener noreferrer"&gt;https://visualgdb.com/gdbreference/commands/&lt;/a&gt;&lt;br&gt;
GDB cheatsheet&lt;br&gt;
&lt;a href="https://cs.brown.edu/courses/cs033/docs/guides/gdb.pdf" rel="noopener noreferrer"&gt;https://cs.brown.edu/courses/cs033/docs/guides/gdb.pdf&lt;/a&gt;&lt;br&gt;
[Vídeo] Introdução ao GNU Debugger - Blau Araújo&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=t9OKpBKbJ4Q" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=t9OKpBKbJ4Q&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

</description>
      <category>computerscience</category>
      <category>braziliandevs</category>
      <category>assembly</category>
    </item>
    <item>
      <title>Construindo um web server em Assembly x86, parte III, código de máquina</title>
      <dc:creator>Leandro Proença</dc:creator>
      <pubDate>Tue, 23 Apr 2024 23:18:02 +0000</pubDate>
      <link>https://dev.to/leandronsp/construindo-um-web-server-em-assembly-x86-parte-iii-codigo-de-maquina-bgk</link>
      <guid>https://dev.to/leandronsp/construindo-um-web-server-em-assembly-x86-parte-iii-codigo-de-maquina-bgk</guid>
      <description>&lt;p&gt;Agora que já temos uma &lt;a href="https://dev.to/leandronsp/construindo-um-web-server-em-assembly-x86-parte-ii-historia-e-arquitetura-2jb9"&gt;base de entendimento&lt;/a&gt; sobre hierarquia de memória, arquitetura de CPU e registradores, vamos aplicar estes conceitos em exemplos práticos: construindo programas de computador.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Mas o que é um programa de computador?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Teremos a resposta para esta pergunta ao longo deste artigo. Vamos abordar muitos conceitos, desde código de máquina (o mais importante na minha opinião), a sistemas de numeração binário, decimal e hexadecimal.&lt;/p&gt;

&lt;p&gt;Iremos também compreender opcodes, chamadas de sistema, modo kernel, libc, ASCII, standard streams; e alterar arquivos binários em hexadecimal.&lt;/p&gt;

&lt;p&gt;Ao final deste artigo vamos estar em um patamar de entendimento mais holístico de como um programa é interpretado na CPU. &lt;/p&gt;

&lt;p&gt;Ainda não entraremos em Assembly. Foi escolhido desta forma pois o intuito com esta saga é detalhar ao máximo como as peças de encaixam, e acredito que trazer Assembly sem explicar outros conceitos primordiais pode confundir bastante. &lt;/p&gt;

&lt;p&gt;Também não é esperado que você escreva os códigos de máquina deste artigo, pois aqui &lt;a href="https://github.com/leandronsp/monica/blob/main/example" rel="noopener noreferrer"&gt;neste link&lt;/a&gt; providencio o binário já pronto para que você possa acompanhar com as ferramentas que irei utilizar. Basta apenas baixar o arquivo binário no link fornecido e atribuir permissão de execução com &lt;code&gt;chmod +x&lt;/code&gt;, se necessário.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Lembrando que é importante que esteja em um ambiente Linux, caso contrário não irá funcionar. Se estiver em outro ambiente e não puder virtualizar, poderá acompanhar esta saga apenas lendo, pois a ideia é também trazer muitos conceitos fundamentais de baixo-nível&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ainda não será o código do web server, o programa proposto neste post é bastante simples, mas estamos quase lá. Vamos focar em conceitos fundamentais para que futuros artigos, que cobrem o desenvolvimento do web server, possam ser melhor compreendidos.&lt;/p&gt;

&lt;p&gt;Sem mais delongas, prepare-se para a partir de agora entrar numa espiral de código de máquina e manipulação de memória. &lt;/p&gt;




&lt;h2&gt;
  
  
  Agenda
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
O que é um programa de computador

&lt;ul&gt;
&lt;li&gt;Sistemas Operacionais e Processos&lt;/li&gt;
&lt;li&gt;Um programa deve sempre terminar&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Nosso primeiro programa

&lt;ul&gt;
&lt;li&gt;A linguagem das CPU's, o sistema binário&lt;/li&gt;
&lt;li&gt;O famoso sistema decimal&lt;/li&gt;
&lt;li&gt;Hexadecimal, o queridinho dos computadores&lt;/li&gt;
&lt;li&gt;Opcodes&lt;/li&gt;
&lt;li&gt;Endianness&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Nosso segundo programa

&lt;ul&gt;
&lt;li&gt;Alocando dados na memória do programa&lt;/li&gt;
&lt;li&gt;ASCII&lt;/li&gt;
&lt;li&gt;Syscalls&lt;/li&gt;
&lt;li&gt;Montando a syscall write&lt;/li&gt;
&lt;li&gt;Montando a syscall exit&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Manipulando o nosso programa&lt;/li&gt;

&lt;li&gt;A vida de quem programa é assim?&lt;/li&gt;

&lt;li&gt;Conclusão&lt;/li&gt;

&lt;li&gt;Referências&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  O que é um programa de computador
&lt;/h2&gt;

&lt;p&gt;Como já vimos na parte II, a função primordial de uma CPU é ler uma instrução da memória, decodificar, executar e armazenar o resultado de volta na memória.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F74pip1fwevxzhlgtskrq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F74pip1fwevxzhlgtskrq.png" alt="CPU decodifica instrução"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Então a grosso modo, um programa de computador é um conjunto de instruções pra a CPU processar. Em um cenário típico, teríamos diversos programas diferentes &lt;strong&gt;lendo e escrevendo&lt;/strong&gt; da mesma memória do computador:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv04zatlsnnkesdegjknq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv04zatlsnnkesdegjknq.png" alt="programas e memória"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mas um potencial problema, é que neste cenário poderíamos ter dois diferentes programas acessando ou modificando o mesmo endereço de memória:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frcdxz981arzq3d9h5e1b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frcdxz981arzq3d9h5e1b.png" alt="conflito em memória"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pra resolver isto, precisamos agrupar as instruções de um programa de modo a "isolar" de outros programas que também estão rodando no computador. &lt;/p&gt;

&lt;p&gt;É aí que entra um dos papéis do &lt;strong&gt;sistema operacional&lt;/strong&gt; com o conceito de &lt;em&gt;processos&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Lembrando que nesta saga, vamos focar apenas em sistemas UNIX-like, mais precisamente distruibuições GNU/Linux&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  🔵 Sistemas Operacionais e Processos
&lt;/h3&gt;

&lt;p&gt;Cada programa executado no SO é encapsulado em uma estrutura chamada &lt;em&gt;processo&lt;/em&gt;, que vai ter uma área virtual na memória principal.&lt;/p&gt;

&lt;p&gt;Na prática, cada programa vai ter seu próprio "0x10000", isolado dos demais.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fra2p8vkdu9pu3tgthvsk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fra2p8vkdu9pu3tgthvsk.png" alt="sistemas operacionais e processos"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🔵 Um programa deve sempre terminar
&lt;/h3&gt;

&lt;p&gt;Como o SO aloca recursos de memória (dentre outros) para o processo, nosso programa precisa indicar quando termina.&lt;/p&gt;

&lt;p&gt;Desta forma aquele espaço reservado de memória fica livre para ser utilizado por outro processo. Isto evita problemas como vazamento de memória entre outros.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbh2z34wvdqii8nz7w3bm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbh2z34wvdqii8nz7w3bm.png" alt="program exit"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Caso isto não seja feito, o SO vai lançar uma exceção e o programa não pode ser admitido como processo.&lt;/p&gt;




&lt;h2&gt;
  
  
  Nosso primeiro programa
&lt;/h2&gt;

&lt;p&gt;Vamos trabalhar inicialmente com um exemplo bastante simples. Um programa que &lt;em&gt;não faz nada&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Nossa Leandro, como assim um programa que não faz nada?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sim, parece estranho para linguagens de mais alto nível. Mas pensando em CPU isto já é alguma coisa, pelo que precisamos de ao menos algumas instruções para um programa que "não faz nada": &lt;strong&gt;o programa precisa terminar&lt;/strong&gt;, lembra?.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔵 A linguagem das CPU's, o sistema binário
&lt;/h3&gt;

&lt;p&gt;Pensando na CPU como um dispositivo eletrônico, esta só entende pulso elétrico. Mas conseguimos abstrair tais pulsos como 0 ou 1. &lt;/p&gt;

&lt;p&gt;Consequentemente, quando falamos em código de máquina para uma CPU estamos falando em instruções que utilizam &lt;em&gt;sistema binário&lt;/em&gt;, composto de 0 ou 1.&lt;/p&gt;

&lt;p&gt;Nosso programa que não faz nada além de "terminar" pode ser representado então pelo seguinte conjunto de instruções:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Não se preocupe em escrever o programa. Por enquanto são só exemplos de código de máquina para que possamos entender bem os conceitos&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

10111111 00000001 00000000 00000000 00000000   
10111000 00111100 00000000 00000000 00000000  
00001111 00000101                            


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;No sistema binário, cada símbolo é chamado de &lt;strong&gt;bit&lt;/strong&gt;. Este simples programa tem 12 conjuntos de 8 bits cada. &lt;em&gt;Conte você mesmo para confirmar!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;O &lt;strong&gt;sistema binário&lt;/strong&gt; tem esse nome porque só fornece dois tipos de símbolos para representar números. Vamos contar:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

0
1


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Acabou. Com 1 dígito podemos ter 2 combinações apenas. Mas e se quisermos representar mais números? Aí nos resta ficar combinando com mais dígitos.&lt;/p&gt;

&lt;p&gt;Para 2 dígitos, conseguimos aumentar para 4 combinações:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

00
01
10
11


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Se quisermos continuar, temos que entrar com 3 dígitos, sempre começando com o mais à esquerda possível, o que nos dá 8 combinações:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

000 
001 
010 
100
100 
101 
110 
111


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Com isto, temos um padrão:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1 dígito: 2 combinações&lt;/li&gt;
&lt;li&gt;2 dígitos: 4 combinações&lt;/li&gt;
&lt;li&gt;3 dígitos: 8 combinações&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Repare no padrão de exponenciação. Estamos pegando o número 2 como base e aplicando o número do dígito como expoente:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;numero de símbolos ^ número de dígitos&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;2^1 = 2&lt;/li&gt;
&lt;li&gt;2^2 = 4&lt;/li&gt;
&lt;li&gt;2^3 = 8&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Extrapolando para 4 ou mais dígitos, podemos chegar na seguinte conclusão:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;2^4 = 16 combinações&lt;/li&gt;
&lt;li&gt;2^5 = 32 combinações&lt;/li&gt;
&lt;li&gt;2^6 = 64 combinações&lt;/li&gt;
&lt;li&gt;2^7 = 128 combinações&lt;/li&gt;
&lt;li&gt;2^8 = 256 combinações&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;E assim por diante...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Você tá brincando com minha cara, né Leandro? Vim aqui pra ficar escovando bit?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Não exatamente. No programa, cada conjunto ali de 8 bits (chamado de &lt;strong&gt;byte&lt;/strong&gt;) tem um significado para a CPU, o que faz nosso programa ter 12 bytes. &lt;/p&gt;

&lt;p&gt;E como não somos uma CPU, estamos nada preocupados em representar instruções em bits, vamos então converter para o sistema decimal para conseguirmos representar nosso &lt;strong&gt;mesmo programa&lt;/strong&gt; de forma mais simples e intuitiva.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔵 O famoso sistema decimal
&lt;/h3&gt;

&lt;p&gt;Já estamos habituados com o sistema decimal. Muitos números no nosso dia-dia são representados através do sistema decimal.&lt;/p&gt;

&lt;p&gt;Falamos de números como "dez", "cento e quinze", "quarenta e dois" sem qualquer problema, pois foi o que aprendemos desde a primeira infância. Nosso cérebro já fixou o aprendizado tão intrinsicamente, que sequer pensamos que se trata de um sistema de numeração como qualquer outro.&lt;/p&gt;

&lt;p&gt;Vamos por um momento &lt;em&gt;esquecer&lt;/em&gt; que sabemos sistema decimal e aplicar as mesmas regras que aplicamos para o sistema binário.&lt;/p&gt;

&lt;p&gt;Repetindo mais uma vez, no sistema binário temos à disposição apenas dois símbolos: 0 e 1. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;E no decimal? &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Temos &lt;strong&gt;dez&lt;/strong&gt; símbolos à disposição, que são:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

0 1 2 3 4 5 6 7 8 9


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Tal como no sistema binário, com 1 dígito apenas temos essas 10 possibilidades acima.&lt;/p&gt;

&lt;p&gt;Já chegou no nove? Acabaram as combinações? Não tem problema, vamos subir pra &lt;em&gt;dois dígitos&lt;/em&gt; sempre começando pelo dígito mais à equerda possível:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

00 01 02 03 04 05 06 07 08 09
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
...
...........................99


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Olha só, com apenas dois dígitos no sistema decimal, podemos combinar 100 números diferentes!&lt;/p&gt;

&lt;p&gt;O padrão é o mesmo no sistema binário, podemos logo aplicar exponenciação da base, sendo:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;numero de símbolos ^ número de dígitos&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Portanto:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;10^2 = 100 combinações&lt;/li&gt;
&lt;li&gt;10^3 = 1000 combinações&lt;/li&gt;
&lt;li&gt;10^4 = 10000 combinações&lt;/li&gt;
&lt;li&gt;etc etc etc&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Convertendo binário em decimal
&lt;/h3&gt;

&lt;p&gt;Uma vez que entendendo sistemas de numeração binário e decimal, podemos "compactar" nosso programa inicial de binário para decimal de modo a termos uma leitura mais intuitiva, não?&lt;/p&gt;

&lt;p&gt;Aplicando a regra de exponenciação, não fica difícil fazer a conversão:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;0 é sempre 0, pois este símbolo está presente em ambos sistemas de numeração&lt;/li&gt;
&lt;li&gt;Mesmo vale para 1, pois está presente em ambos&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Se quisermos então converter &lt;code&gt;10&lt;/code&gt; (que é o próximo número depois de 1 em binário) de binário pra decimal, vamos aplicar a seguinte regra:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;dígito x 2^posição do dígito&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;...&lt;em&gt;somando o resultado&lt;/em&gt; de cada operação em dígito, onde a posição &lt;strong&gt;mais à direita possível&lt;/strong&gt; começa com &lt;em&gt;zero&lt;/em&gt;, pois de acordo com a senhora matemática, qualquer número elevado a &lt;em&gt;zero&lt;/em&gt; é &lt;em&gt;UM&lt;/em&gt;*.&lt;/p&gt;

&lt;p&gt;Com isto:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;10 = &lt;em&gt;(1 x 2^1) + (0 x 2^0)&lt;/em&gt; = 2 + 0 = &lt;strong&gt;2&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vamos extrapolar um pouquinho?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;11 = &lt;em&gt;(1 x 2^1) + (1 x 2^0)&lt;/em&gt; = 2 + 1 = &lt;strong&gt;3&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;100 = &lt;em&gt;(1 x 2^2) + (0 x 2^1) + (0 x 2^0)&lt;/em&gt; = 2 + 0 + 0 = &lt;strong&gt;4&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yay! &lt;em&gt;Nice, uh?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Agora vamos converter &lt;em&gt;byte a byte&lt;/em&gt; do nosso programa:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

10111111 00000001 00000000 00000000 00000000   
10111000 00111100 00000000 00000000 00000000  
00001111 00000101                            


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;10111111 = &lt;em&gt;(1 x 2^7) + (0 x 2^6) ...&lt;/em&gt; = &lt;strong&gt;191&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;00000001 = &lt;em&gt;(0 x 2^7) + (0 x 2^6) ... + (1 + 2^0)&lt;/em&gt; = &lt;strong&gt;1&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;etc etc etc até chegar ao 12º byte&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Temos então um programa convertido para decimal da seguinte forma:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

191 1 0 0 0
184 60 0 0 0
15 5


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Entretanto, não é comum representar sistema decimal para instruções de CPU, pois cada byte (8 bits) não seria dividido em partes iguais no sistema decimal, o que poderia causar um &lt;em&gt;desalinhamento&lt;/em&gt;, criando buracos desnecessários na memória.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Uma forma de ver este problema é que o sistema decimal composto de 10 símbolos não é divisível por 8 (resto 2), que é a quantidade de bits em um byte&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;E se tivéssemos um sistema de numeração com uma &lt;em&gt;quantidade de dígitos&lt;/em&gt; que fosse divisível por 8? &lt;/p&gt;

&lt;p&gt;Sabendo que 16 é divisível por 8 (resto 0) e não causaria desalinhamento entre bits pra representar um programa, será que existe um sistema de numeração de 16 símbolos para podermos &lt;strong&gt;compactar ainda mais&lt;/strong&gt; a representação textual do nosso programa?&lt;/p&gt;

&lt;p&gt;Sim, estamos falando do &lt;strong&gt;sistema hexadecimal&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔵 Hexadecimal, o queridinho dos computadores
&lt;/h3&gt;

&lt;p&gt;Certamente você já ouviu falar, viu ou até praticou hexadecimal. Similar ao que fizemos com sistema decimal, vamos esquecer tudo o que sabemos sobre hexadecimal e aplicar algumas regras. &lt;/p&gt;

&lt;p&gt;Quantos símbolos temos à disposição? 16.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Daí o nome: &lt;strong&gt;hexa&lt;/strong&gt;, representando 6, e &lt;strong&gt;decimal&lt;/strong&gt; representando 10. DEZ + SEIS!!!!!111&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Os primeiros 10 símbolos são exatamente como no decimal:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

0 1 2 3 4 5 6 7 8 9


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;E quanto aos 6 &lt;strong&gt;símbolos&lt;/strong&gt; restantes? Poderíamos representar emojis, gifs animados ou derivados de batata, mas seria muito mais simples representarmos as primeiras 6 letras do alfabeto, não?&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

0 1 2 3 4 5 6 7 8 9 A B C D E F


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;As regras pra combinar são as mesmas, sempre do mais à esquerda possível:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

0 1 2 3 4 5 6 7 8 9 A B C D E F
10 11 12 13 14 15 16 17 18 19 ?


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Qual seria o próximo? 20?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Não, jovem, vamos combinar com as letras restantes&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

...
19
1A
1B
1C
1D
1E
1F


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Agora sim, as combinações com o dígito 2:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 
30 31 32 33 34 ............................. 3F 
...........................99................9F
100


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Com apenas 2 dígitos no sistema hexadecimal, podemos ter 256 combinações de números diferentes!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;em binário, 2 dígitos = 4 combinações&lt;/li&gt;
&lt;li&gt;em decimal, 2 dígitos = 100 combinações&lt;/li&gt;
&lt;li&gt;em hexa, 2 dígitos = 256 combinações&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Por exemplo, para termos 256 combinações com 2 símbolos &lt;code&gt;FF&lt;/code&gt;, precisaríamos de 8 símbolos &lt;code&gt;1111 1111&lt;/code&gt; no sistema binário, &lt;strong&gt;obviamente ocupando mais espaço&lt;/strong&gt; pra representar e visualizar programas.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;O céu é o limite 🚀&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Aplicando regra de exponenciação para convertermos pra decimal, vamos ter o seguinte:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;do 0 ao 9 é tudo igual&lt;/li&gt;
&lt;li&gt;A = 10, B = 11, C = 12, D = 13, E = 14, F = 15&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Onde:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;dígito do sistema * 16^posição do dígito&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Com isto, convertendo &lt;code&gt;1A&lt;/code&gt; e &lt;code&gt;FF&lt;/code&gt; para decimal, ficaria:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1A = &lt;em&gt;(1 * 16^1) + (10 * 16^0)&lt;/em&gt; = 16 + 10 = &lt;strong&gt;26&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;FF = &lt;em&gt;(15 * 16^1) + (15 * 16^0)&lt;/em&gt; = 240 + 15 = &lt;strong&gt;255&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Ok, mas precisamos converter de binário para hexa&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Com razão, como podemos converter o byte &lt;strong&gt;11111111&lt;/strong&gt; para hexadecimal? Dá pra fazer por dedução da conversão decimal, por exemplo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sabendo que o byte &lt;strong&gt;11111111&lt;/strong&gt; representa 255 em decimal, e sabendo que &lt;code&gt;FF&lt;/code&gt; em decimal é 255,  portanto concluímos que &lt;code&gt;11111111 = FF&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;se dividirmos o byte em 2 partes, podemos calcular que &lt;code&gt;1111 = F&lt;/code&gt;, portanto chegamos no mesmo resultado&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Geralmente empregamos a técnica de dividir o byte em 2 partes de 4 bits cada. Assim fica mais fácil visualizar.&lt;/p&gt;

&lt;p&gt;O simples programa original escrito em binário, fica então convertido em hexadecimal da seguinte forma:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

BF 01 00 00 00 
B8 3C 00 00 00 
0F 05          


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Opa! Já conseguimos ter uma leitura mais intuitiva, certo? Mas que raios significa &lt;code&gt;BF 01&lt;/code&gt;, &lt;code&gt;B8 3C&lt;/code&gt; ou &lt;code&gt;0F 05&lt;/code&gt; na CPU?&lt;/p&gt;

&lt;h3&gt;
  
  
  🔵 Opcodes
&lt;/h3&gt;

&lt;p&gt;Cada CPU possui uma arquitetura específica. Falando de x64 (ou x86_64), esta traz um conjunto de &lt;strong&gt;opcodes&lt;/strong&gt; no manual que representam as instruções disponíveis, registradores entre outras operações de CPU.&lt;/p&gt;

&lt;p&gt;De acordo com o &lt;a href="http://ref.x86asm.net/coder64.html" rel="noopener noreferrer"&gt;manual&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;o opcode &lt;code&gt;BF&lt;/code&gt; move um valor imediato para o registrador RDI&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;01 00 00 00&lt;/code&gt;: valor imediato hexa que representa &lt;code&gt;1&lt;/code&gt; em decimal, mas na ordem inversa no formato &lt;strong&gt;little-endian&lt;/strong&gt; (vamos falar de endianness mais a seguir)&lt;/li&gt;
&lt;li&gt;o opcode &lt;code&gt;B8&lt;/code&gt; move um valor imediato para o registrador RAX&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;3C 00 00 00&lt;/code&gt;: valor imediato hexa que representa &lt;code&gt;60&lt;/code&gt; em decimal, mas na ordem inversa no formato &lt;strong&gt;little-endian&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;o opcode &lt;code&gt;0F 05&lt;/code&gt; entra no modo "kernel" do SO e aguarda a resposta de uma chamada de sistema (syscall)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mas por quê os bytes são representados na ordem inversa nesta arquitetura de CPU?&lt;/p&gt;

&lt;h3&gt;
  
  
  🔵 Endianness
&lt;/h3&gt;

&lt;p&gt;O conceito de &lt;strong&gt;endianness&lt;/strong&gt; está relacionado com a forma que CPU's lêem e processam bytes na memória.&lt;/p&gt;

&lt;p&gt;Vamos trazer o exemplo de um byte em binário, &lt;code&gt;10000001&lt;/code&gt;, que sabemos que é &lt;code&gt;129&lt;/code&gt; em decimal. Prestando atenção nos expoentes:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;2^7 + 2^6 + 2^5 + 2^4 + 2^3 + 2^2 + 2^1 + 2^0&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;o bit mais à esquerda, &lt;em&gt;1 x 2^7&lt;/em&gt; = 128&lt;/li&gt;
&lt;li&gt;somado com o bit mais à direita, &lt;em&gt;1 x 2^0&lt;/em&gt; = 1&lt;/li&gt;
&lt;li&gt;o restante dos bits está tudo a zero, não precisam entrar pra soma&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Podemos inferir que os bits mais à direita &lt;em&gt;não têm tanto peso&lt;/em&gt; no valor final, por isso são chamados &lt;strong&gt;bits menos significativos&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;O bit da direita incorporou apenas o valor &lt;strong&gt;1&lt;/strong&gt; pro resultado final&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Da mesma forma, os bits mais à esquerda &lt;em&gt;têm mais peso&lt;/em&gt; no valor final, por isso são chamados de &lt;strong&gt;bits mais significativos&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;O bit da esquerda incorporou &lt;strong&gt;128&lt;/strong&gt; pro resultado final, trazendo mais significância&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Esta propriedade de definir significância de bits é chamada de &lt;em&gt;endianness&lt;/em&gt;. Diferentes arquiteturas de CPU podem decidir ler do mais significativo ao menos significativo (padrão intuitivo de leitura, big-endian) ou do menos significativo ao mais significativo (little-endian).&lt;/p&gt;

&lt;p&gt;A decisão passa por fatores históricos ou por facilitar manipulação de ponteiros. Diferentes sistemas podem decidir por inverter a leitura/escrita ou não dos bytes.&lt;/p&gt;

&lt;p&gt;Na CPU x86_64, o formato é &lt;strong&gt;little-endian&lt;/strong&gt;, portanto em hexa o valor de 4 bytes &lt;code&gt;00 0D 00 3C&lt;/code&gt; passa a ser &lt;code&gt;3C 00 0D 00&lt;/code&gt; no formato little-endian.&lt;/p&gt;

&lt;p&gt;Concluindo, vamos adicionar comentários ao nosso pseudo-programa:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

BF 01 00 00 00  ; MOVE 1 PARA RDI
B8 3C 00 00 00  ; MOVE 60 PARA RAX
0F 05           ; CHAMADA DE SISTEMA (SYSCALL)


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Como a CPU sabe qual syscall deve executar? Por padrão, o número da syscall fica no registrador &lt;code&gt;RAX&lt;/code&gt;. E como saber qual o número da syscall?&lt;/p&gt;

&lt;p&gt;Neste &lt;a href="https://x64.syscall.sh/" rel="noopener noreferrer"&gt;link&lt;/a&gt;, temos uma lista completa de todas as syscalls da arquitetura x64, e ali podemos conferir que a syscall &lt;code&gt;exit&lt;/code&gt; do kernel representa o número 60 decimal, ou &lt;em&gt;3C&lt;/em&gt; hexa. É exatamente o que a instrução &lt;code&gt;B8 3C&lt;/code&gt; está fazendo! &lt;/p&gt;

&lt;p&gt;Mais a seguir neste artigo vamos aprofundar no mundo das syscalls e chamadas do kernel.&lt;/p&gt;




&lt;h2&gt;
  
  
  Nosso segundo programa
&lt;/h2&gt;

&lt;p&gt;Até agora vimos apenas o código de máquina de um programa que não faz nada (apenas termina), mas foi bastante útil para entendermos sistema binário, hexadecimal e outros conceitos.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Continuaremos ainda explorando código de máquina. Não precisa escrever nada, mas pode acompanhar com o &lt;a href="https://github.com/leandronsp/monica/blob/main/example" rel="noopener noreferrer"&gt;código que disponibilizei&lt;/a&gt; no início do artigo e rodar os comandos em Linux&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Vamos agora elaborar um hipotético programa que imprime "Hello, World" na saída (STDOUT). Para isto, devemos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;alocar memória para a string "Hello, World"&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Sim, dados ficam na memória junto com o programa, lembra?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;escrever a string na saída STDOUT, que é a saída padrão do programa (em outras palavras, a "tela")&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Se quiser mais detalhes do que é STDOUT, standard streams e redirecionamento de streams, sugiro ler &lt;a href="https://dev.to/leandronsp/entendendo-unix-pipes-3k56"&gt;outros artigos&lt;/a&gt; que escrevi sobre UNIX pipes&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;terminar o programa&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Alocar, imprimir, terminar&lt;/em&gt;. Escrever no STDOUT é uma chamada de sistema, e terminar o programa é &lt;strong&gt;outra&lt;/strong&gt; chamada de sistema. Portanto, temos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;uma alocação de dados na memória do programa&lt;/li&gt;
&lt;li&gt;2 chamadas de sistema&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🔵 Alocando dados na memória do programa
&lt;/h3&gt;

&lt;p&gt;Em linguagem de máquina, fazemos alocação byte a byte, e sabendo que queremos alocar "Hello, World" &lt;em&gt;literalmente&lt;/em&gt;, como representar cada letra, o caracter &lt;em&gt;vírgula&lt;/em&gt; e o caracter &lt;em&gt;espaço&lt;/em&gt; na memória?&lt;/p&gt;

&lt;p&gt;Precisamos de uma tradução dos caracteres para representação decimal ou hexadecimal. É isso mesmo que você está lendo, vamos entrar em &lt;strong&gt;ASCII&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔵 ASCII
&lt;/h3&gt;

&lt;p&gt;ASCII (American Standard Code for Information Interchange), é um padrão para codificação de caracteres em comunicação eletrônica, criado nos anos 60.&lt;/p&gt;

&lt;p&gt;O padrão ASCII estabeleceu inicialmente 7 bits para cada caracter e foi concebido para suportar caracteres presentes somente na língua inglesa. Por conta desta limitação, tem suporte para um máximo de 128 caracteres (2^7) que abordam os dígitos decimais, caracteres especais e letras do alfabeto, maiúsculas e minúsculas.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft80bwvjweywmtmghmnvt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft80bwvjweywmtmghmnvt.png" alt="tabela ASCII"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mais tarde veio uma extensão da tabela com um bit a mais portanto suportando mais caracteres como acentuações, porém ainda com limitações para suportar outros idiomas e caracteres especiais.&lt;/p&gt;

&lt;p&gt;Tempos depois surgiu o padrão &lt;strong&gt;Unicode&lt;/strong&gt;, que adiciona a capacidade de codificação de tamanho variável, permitindo assim uma multitude de caracteres e alfabetos de diversos idiomas.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Unicode também contempla a mesma tabela ASCII nos primeiros 128 caracteres por questões de retrocompatibilidade em sistemas. Portanto, apesar de sistemas modernos utilizarem esquemas de codificação Unicode tais como UTF-8, neste artigo focaremos na terminologia ASCII por ser suficiente nos nossos exemplos&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Podemos verificar na tabela ASCII que os códigos hexa de cada caractere da nossa string são:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

H: 0x48     
e: 0x65     
l: 0x6C     
l: 0x6C     
o: 0x6F
,: 0x2C

W: 0x57
o: 0x6F
r: 0x72
l: 0x6C
d: 0x64



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;0x&lt;/strong&gt; é uma notação, um prefixo para determinar que o número depois de &lt;em&gt;x&lt;/em&gt; é um hexadecimal&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Com isto podemos então escrever os primeiros bytes hexa do nosso programa:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 0A


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Nice, agora vamos "montar" as instruções para a syscall que &lt;em&gt;escreve no STDOUT&lt;/em&gt;. Como o kernel faz isso? &lt;/p&gt;

&lt;h3&gt;
  
  
  🔵 Syscalls
&lt;/h3&gt;

&lt;p&gt;Syscalls são &lt;strong&gt;chamadas de sistema&lt;/strong&gt; onde o programa sai do modo "user" e entra no modo "kernel". Basicamente, o programa fica à espera que o kernel do sistema operacional execute a função que foi solicitada.&lt;/p&gt;

&lt;p&gt;Apesar de &lt;a href="https://x64.syscall.sh/" rel="noopener noreferrer"&gt;neste link&lt;/a&gt; estar tudo compilado, temos que entender um fator muito importante sobre o kernel que estamos trabalhando, e se trata do &lt;strong&gt;kernel Linux&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;O &lt;a href="https://en.wikipedia.org/wiki/Linux_kernel" rel="noopener noreferrer"&gt;kernel Linux&lt;/a&gt; foi escrito em C na virada da década de 80 para 90, e por ser escrito em C, todas as chamadas de sistema são declaradas em C.&lt;/p&gt;

&lt;p&gt;Por exemplo, no &lt;a href="https://man7.org/linux/man-pages/index.html" rel="noopener noreferrer"&gt;manual de system calls&lt;/a&gt; do kernel podemos pesquisar sobre qualquer chamada de sistema ou comando utilitário.&lt;/p&gt;

&lt;p&gt;A chamada que queremos utilizar pra escrever no STDOUT se chama &lt;a href="https://man7.org/linux/man-pages/man2/write.2.html" rel="noopener noreferrer"&gt;write&lt;/a&gt;, e é definida pela função:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;

&lt;span class="kt"&gt;ssize_t&lt;/span&gt; &lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;[.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;...que está presente na biblioteca padrão C (libc), que o kernel incorpora. &lt;/p&gt;

&lt;p&gt;Para distribuições GNU, que é o meu caso utilizando Ubuntu, há um repositório mirror do &lt;code&gt;glibc&lt;/code&gt; que é a biblioteca padrão em C para sistemas GNU/Linux.&lt;/p&gt;

&lt;p&gt;Repara que a função &lt;code&gt;write&lt;/code&gt; espera 3 argumentos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;fd&lt;/code&gt;, ou file descriptor, que no nosso caso é o STDOUT, representado pelo valor 1&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;STDIN&lt;/strong&gt; representa 0 e &lt;strong&gt;STDERR&lt;/strong&gt; representa 2. Tá lá no nosso outro artigo sobre Bash e UNIX pipes, corre dar uma olhada&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;buf&lt;/code&gt;, ou buffer, que é o ponteiro para o início do buffer de dados. No caso de escrever "Hello, World" com quebra de linha, o buf apontaria para o início da string "Hello, World\n" na memória.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;count&lt;/code&gt;, que é o tamanho do buffer de dados a ser escrito. Para a string "Hello, World\n", o count seria 13, pois isso inclui os 12 caracteres da string mais 1 byte para a quebra de linha.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🔵 Montando a syscall write
&lt;/h3&gt;

&lt;p&gt;Para montar uma chamada de sistema, é necessário seguir uma &lt;em&gt;interface&lt;/em&gt; que determina como um programa deve comunicar com o sistema operacional.&lt;/p&gt;

&lt;p&gt;Quem determina isto é a ABI (Application Binary Interface), que define como estruturas de dados ou funções computacionais conversam entre si. &lt;/p&gt;

&lt;p&gt;Como precisamos chamar uma função do kernel Linux, vamos utilizar as &lt;a href="https://en.wikipedia.org/wiki/X86_calling_conventions" rel="noopener noreferrer"&gt;convenções determinadas&lt;/a&gt; por este sistema operacional e a arquitetura da CPU em questão.&lt;/p&gt;

&lt;p&gt;Com isto, podemos montar as instruções utilizando registradores para a syscall &lt;code&gt;write&lt;/code&gt;. Novamente seguindo &lt;a href="https://x64.syscall.sh/" rel="noopener noreferrer"&gt;esta tabela&lt;/a&gt; (que ajuda muito), vamos fazer instrução por instrução:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;ARG0&lt;/strong&gt;&lt;br&gt;
O primeiro argumento da função vai no registrador RDI, e aqui vamos colocar o valor &lt;code&gt;1&lt;/code&gt; que representa o &lt;em&gt;file descriptor&lt;/em&gt; STDOUT. Em hexa, o &lt;a href="http://ref.x86asm.net/coder64.html" rel="noopener noreferrer"&gt;manual x86&lt;/a&gt; diz que o opcode hexa é &lt;code&gt;BF&lt;/code&gt;, seguido do hexa &lt;code&gt;00 00 00 01&lt;/code&gt; em formato little-endian:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

BF 01 00 00 00


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;👉 &lt;strong&gt;ARG1&lt;/strong&gt;&lt;br&gt;
O segundo argumento é o ponteiro para o buffer onde começa a string na memória, movido para o registrador RSI. &lt;/p&gt;

&lt;p&gt;Como a string fica no começo do programa, geralmente este endereço fica em &lt;code&gt;0x401000&lt;/code&gt;. Portanto, o opcode para o &lt;code&gt;move&lt;/code&gt; no registrador é &lt;code&gt;48 BE&lt;/code&gt; e o valor do endereço de memoria no formato little-endian em hexa, &lt;code&gt;00 10 40&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

48 BE 00 10 40 


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;👉 &lt;strong&gt;ARG2&lt;/strong&gt;&lt;br&gt;
Já o terceiro argumento da função vai para o registrador RDX, que representa o tamanho do buffer em bytes a ser escrito no file descriptor definido no registrador RDI (ARG0).&lt;/p&gt;

&lt;p&gt;O opcode é o &lt;code&gt;BA&lt;/code&gt; e o valor é &lt;code&gt;13&lt;/code&gt; em hexa, que é &lt;code&gt;00 00 00 0D&lt;/code&gt; só que no formato little-endian:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

BA 0D 00 00 00


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Agora, vamos colocar no registrador RAX o número da syscall &lt;strong&gt;write&lt;/strong&gt;, que de acordo com &lt;a href="https://x64.syscall.sh/" rel="noopener noreferrer"&gt;esta tabela&lt;/a&gt; (sempre esta tabela, habitue-se a ela), é o número 1, mas em hexa e little-endian:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

B8 01 00 00 00


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Falei bastante desta tabela, de syscalls e little-endian aqui, nos próximos artigos vou falar cada vez menos. A ideia é focar em outras coisas e estes detalhes estarem já bem fundamentados&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Por último, vamos montar a instrução da syscall em si, que é o opcode:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

0F 05


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Trecho final da syscall write:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 0A ; "Hello, World"

BF 01 00 00 00                 ; MOV 1 para RDI
48 BE 00 10 40                 ; MOV 0x401000 para RSI
BA 0D 00 00 00                 ; MOV 13 para RDX
B8 01 00 00 00                 ; MOV 1 para RAX (write)
0F 05                          ; SYSCALL


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;A syscall &lt;code&gt;write&lt;/code&gt; já tá montada, agora falta terminar o programa.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔵 Montando a syscall exit
&lt;/h3&gt;

&lt;p&gt;A API da chamada de sistema &lt;strong&gt;exit&lt;/strong&gt; pode ser consultada no &lt;a href="https://man7.org/linux/man-pages/man2/_exit.2.html" rel="noopener noreferrer"&gt;manual&lt;/a&gt;, e tem a seguinte assinatura no &lt;code&gt;glibc&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;_exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;👉 &lt;strong&gt;ARG0&lt;/strong&gt;&lt;br&gt;
O primeiro argumento é o status de término, que de acordo com a especificação &lt;a href="https://en.wikipedia.org/wiki/POSIX" rel="noopener noreferrer"&gt;POSIX&lt;/a&gt;, pode ser qualquer inteiro de 0 a 255 mas sendo o 0 indicando que o progama terminou sem erros.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

BF 00 00 00 00


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Agora, vamos ao trecho final da syscall &lt;em&gt;exit&lt;/em&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

BF 00 00 00 00          ; MOV 0 para RDI
B8 3C 00 00 00          ; MOV 60 para RAX (exit)
0F 05                   ; SYSCALL


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Programa completo:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 0A
BF 01 00 00 00 
48 BE 00 10 40
BA 0D 00 00 00 
B8 01 00 00 00 
0F 05          
BF 00 00 00 00 
B8 3C 00 00 00 
0F 05          


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Tomando como exemplo o &lt;a href="https://github.com/leandronsp/monica/blob/main/example" rel="noopener noreferrer"&gt;binário que disponibilizei&lt;/a&gt;, ele tem mais bytes por conta de headers necessários para o próprio sistema operacional admitir o programa. &lt;/p&gt;

&lt;p&gt;Vamos executar o binário:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;./example

Hello, world


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Yay! Que dia, hein?&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Manipulando o nosso programa
&lt;/h2&gt;

&lt;p&gt;Com o arquivo binário em mãos, e sugiro baixar do &lt;a href="https://github.com/leandronsp/monica/blob/main/example" rel="noopener noreferrer"&gt;repositório&lt;/a&gt;, vamos utilizar o utilitário &lt;code&gt;xxd&lt;/code&gt; que faz um dump de hexa de qualquer binário, e com ele podemos reparar que o binário vai ter, a partir do byte &lt;em&gt;4096&lt;/em&gt;, a mesma quantidade de bytes que escrevemos aqui neste artigo:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

xxd &lt;span class="nt"&gt;-s&lt;/span&gt; 4096 &lt;span class="nt"&gt;-g1&lt;/span&gt; &lt;span class="nt"&gt;-c8&lt;/span&gt; &lt;span class="nt"&gt;-l52&lt;/span&gt; example

00001000: 48 65 6c 6c 6f 2c 20 57  Hello, W
00001008: 6f 72 6c 64 0a bf 01 00  orld....
00001010: 00 00 48 be 00 10 40 00  ..H...@.
00001018: 00 00 00 00 ba 0d 00 00  ........
00001020: 00 b8 01 00 00 00 0f 05  ........
00001028: bf 00 00 00 00 b8 3c 00  ......&amp;lt;&lt;span class="nb"&gt;.&lt;/span&gt;
00001030: 00 00 0f 05              ....


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Maravilhoso, não?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;E por fim, antes de concluir este artigo que por si só dá quase uma saga, vamos alterar o binário direto em código de máquina utilizando o utilitário &lt;code&gt;hexedit&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Esta dica peguei em &lt;a href="https://www.youtube.com/@debxp" rel="noopener noreferrer"&gt;vídeos do Blau Araújo&lt;/a&gt;. Ele é realmente fantástico e traz conteúdo de primeira. Pra mim é a melhor referência para conteúdo de baixo nível em pt-BR&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Para mudar o binário, rodamos o comando:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

hexedit &lt;span class="nt"&gt;--color&lt;/span&gt; example


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Que vai abrir um editor bastante específico. Com &lt;code&gt;/&lt;/code&gt;, podemos buscar por um hexa, por exemplo "48", que vai levar para o início da string. &lt;/p&gt;

&lt;p&gt;Vamos trocar o "W" maiúsculo por "w" minúsculo, diretamente em código de máquina, que significa trocar o byte &lt;strong&gt;57&lt;/strong&gt; da tabela ASCII por &lt;strong&gt;77&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Então:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

48 65 6C 6C  6F 2C 20 57  6F 72 6C 64  0A 


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Passa a ser:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

48 65 6C 6C  6F 2C 20 77  6F 72 6C 64  0A 


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Gravar o arquivo com &lt;strong&gt;ctrl+s&lt;/strong&gt; e depois &lt;strong&gt;ctrl+c&lt;/strong&gt; para sair. Executar novamente e:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;./example

Hello, world


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;MEO DEOS, impressionante!!!!111&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  A vida de quem programa é assim?
&lt;/h2&gt;

&lt;p&gt;Leitores mais atentos devem estar se perguntando:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;É sempre assim a vida de quem programa? Ficar escovando bits e mudar diretamente código de máquina em hexadecimal?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Para a maioria esmagadora dos casos, não.&lt;/p&gt;

&lt;p&gt;E se a gente criasse um programa tradutor que nos permitisse &lt;em&gt;montar as instruções&lt;/em&gt; em uma linguagem mais &lt;em&gt;human-friendly&lt;/em&gt; e traduzisse para o código de máquina tal o que vimos aqui neste artigo?&lt;/p&gt;

&lt;p&gt;Estamos falando de &lt;strong&gt;assemblers&lt;/strong&gt;, que são montadores que permitem escrever em uma linguagem de montagem específica de uma arquitetura (um assembly) e converter para os opcodes, as instruções de CPU.&lt;/p&gt;

&lt;p&gt;Reforçando, nesta saga vamos focar no montador NASM para a linguagem Assembly x86 de 64-bits em sistemas GNU/Linux.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Jornada longa essa, hein? Este artigo cobriu diversos conceitos fundamentais, tais como sistema binário, hexadecimal, opcodes, syscalls, libc, ASCII...&lt;/p&gt;

&lt;p&gt;Estes conceitos fundamentam o entendimento para escrever código Assembly, que será o tema principal dos próximos artigos.&lt;/p&gt;

&lt;p&gt;No próximo artigo, vamos abordar conceitos básicos de Assembly, buscando converter o simples programa que fizemos neste artigo em um &lt;strong&gt;asm&lt;/strong&gt; (atalho pra dizer "assembly") bem organizadinho. &lt;/p&gt;

&lt;p&gt;Em seguida, iremos entrar nas syscalls de socket, bind e accept justamente para montarmos o código do nosso web server. Vamos também manipular buffer de arquivos, alocar dados dinamicamente na memória, trabalhar com threads, locks, criar fila na mão, enfim, ainda há muita coisa por vir. Isto aqui é apenas &lt;em&gt;a ponta do iceberg&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Não será um tutorial, mas vamos falar de mnemonics, endereçamento de memória, segmentos de memória, layout de memória de um programa, debugging com &lt;strong&gt;gdb&lt;/strong&gt; entre outras coisas.&lt;/p&gt;

&lt;p&gt;Fiquem ligades!&lt;/p&gt;




&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;p&gt;&lt;br&gt;
Blau Araújo, material de curso de Assembly&lt;br&gt;
&lt;a href="https://codeberg.org/blau_araujo/assembly-nasm-x86_64/raw/branch/main/pdf/aula01.pdf" rel="noopener noreferrer"&gt;https://codeberg.org/blau_araujo/assembly-nasm-x86_64/raw/branch/main/pdf/aula01.pdf&lt;/a&gt;&lt;br&gt;
Felix Cloutier, "x86 instruction reference"&lt;br&gt;
&lt;a href="https://www.felixcloutier.com/x86/" rel="noopener noreferrer"&gt;https://www.felixcloutier.com/x86/&lt;/a&gt;&lt;br&gt;
ASCII Table&lt;br&gt;
&lt;a href="https://upload.wikimedia.org/wikipedia/commons/thumb/1/1b/ASCII-Table-wide.svg/2560px-ASCII-Table-wide.svg.png" rel="noopener noreferrer"&gt;https://upload.wikimedia.org/wikipedia/commons/thumb/1/1b/ASCII-Table-wide.svg/2560px-ASCII-Table-wide.svg.png&lt;/a&gt;&lt;br&gt;
POSIX, Wikipedia&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/POSIX" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/POSIX&lt;/a&gt;&lt;br&gt;
ASM x86 Manual&lt;br&gt;
&lt;a href="http://ref.x86asm.net/coder64.html" rel="noopener noreferrer"&gt;http://ref.x86asm.net/coder64.html&lt;/a&gt;&lt;br&gt;
Syscalls table&lt;br&gt;
&lt;a href="https://x64.syscall.sh/" rel="noopener noreferrer"&gt;https://x64.syscall.sh/&lt;/a&gt;&lt;br&gt;
Linux Kernel, Wikipedia&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Linux_kernel" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Linux_kernel&lt;/a&gt;&lt;br&gt;
ABI, Wikipedia&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Application_binary_interface" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Application_binary_interface&lt;/a&gt;&lt;br&gt;
x86 calling conventions&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/X86_calling_conventions" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/X86_calling_conventions&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

</description>
      <category>assembly</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Construindo um web server em Assembly x86, parte II, história e arquitetura</title>
      <dc:creator>Leandro Proença</dc:creator>
      <pubDate>Thu, 11 Apr 2024 23:26:28 +0000</pubDate>
      <link>https://dev.to/leandronsp/construindo-um-web-server-em-assembly-x86-parte-ii-historia-e-arquitetura-2jb9</link>
      <guid>https://dev.to/leandronsp/construindo-um-web-server-em-assembly-x86-parte-ii-historia-e-arquitetura-2jb9</guid>
      <description>&lt;p&gt;No &lt;a href="https://dev.to/leandronsp/construindo-um-web-server-em-assembly-x86-parte-i-introducao-14p5"&gt;artigo anterior&lt;/a&gt; demos uma introdução não-técnica sobre o que será esta saga de Assembly x86 conforme avançamos na construção de um web server.&lt;/p&gt;

&lt;p&gt;Agora, chegou o momento de começarmos a de fato falar sobre coisas técnicas. &lt;/p&gt;

&lt;p&gt;Como de costume, não gosto de esgormitar termos complexos sem a devida explicação. Portanto, vamos iniciar a saga trazendo um pouco de contexto histórico, motivações e porque estamos aqui quando o assunto é &lt;strong&gt;computadores&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Okay, agora fui filósofo demais. Mas o que mais importa é que o verdadeiro Assembly são os amigos que fazemos no caminho&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sem mais delongas, vamos ao que interessa.&lt;/p&gt;




&lt;h2&gt;
  
  
  Agenda
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Um pouco de história&lt;/li&gt;
&lt;li&gt;
Computar informações

&lt;ul&gt;
&lt;li&gt;Máquina de Turing&lt;/li&gt;
&lt;li&gt;Arquitetura de von Neumann&lt;/li&gt;
&lt;li&gt;O gargalo de von Neumann&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Hierarquia de memória

&lt;ul&gt;
&lt;li&gt;Como a CPU executa instruções&lt;/li&gt;
&lt;li&gt;Registradores de CPU&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

ISA

&lt;ul&gt;
&lt;li&gt;CISC&lt;/li&gt;
&lt;li&gt;RISC&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Por quê x86?&lt;/li&gt;

&lt;li&gt;Conclusão&lt;/li&gt;

&lt;li&gt;Referências&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  Um pouco de história
&lt;/h2&gt;

&lt;p&gt;Ainda muitos milhares de anos a.C, o ser humano precisava realizar cálculos. Um dos instrumentos mais primitivos para esta tarefa era o Ábaco, e certamente você já deve ter visto um:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4rnhwceutwrg1kxc1amx.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4rnhwceutwrg1kxc1amx.jpeg" alt="abaco"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Não vou entrar em detalhes em como um Ábaco funciona, sugiro que compre um e experimente. É divertido. Eu usei quando estava no ensino primário (cria dos anos 90, cof cof).&lt;/p&gt;

&lt;h3&gt;
  
  
  Computadores mecânicos
&lt;/h3&gt;

&lt;p&gt;Ainda nesta "pré-história" dos computadores e já avançando para uma Europa iluminista (circa século XVII), podemos ver a seguir invenções mecânicas e projetos como a máquina de calcular de Blaise Pascal, depois a máquina analítica de Charles Babbage e então a máquina de tabulação de Herman Hollerith.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F96zo1kt2of9iohmx3f02.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F96zo1kt2of9iohmx3f02.jpeg" alt="babbage machine"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 É da máquina de tabulação de Herman Hollerith que vem o nome do seu comprovante de pagamento "holerite"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Estas máquinas eram mecânicas e tinham muitas limitações como não ter uma memória própria para as "instruções", mas foram muito importantes para a evolução, possibilitando mais tarde que Ada Lovelace pudesse escrever o primeiro possível algoritmo para o projeto da máquina de Babbage.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pra quem quiser uma explicação excelente e mais completa sobre a história dos computadores e como estes funcionam, sugiro o vídeo &lt;a href="https://www.youtube.com/watch?v=BbnDmeNojFA" rel="noopener noreferrer"&gt;como reinventar um computador do zero&lt;/a&gt; do canal Infinitamente.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Computar informações
&lt;/h2&gt;

&lt;p&gt;Na era moderna dos computadores, que se dá início no século XX, é quando acontece a revolução eletrônica através das válvulas e dos transistores. &lt;/p&gt;

&lt;p&gt;Mas não apenas na área da eletrônica. Foi no século XX que vimos a revolução computacional através de um modelo abstrato que abriu portas para muito do que conhecemos hoje em termos de computadores.&lt;/p&gt;

&lt;p&gt;Estamos falando da &lt;strong&gt;máquina de Turing&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Máquina de Turing
&lt;/h3&gt;

&lt;p&gt;Nos anos 30, o matemático Alan Turing desenvolveu o conceito abstrato de uma máquina que possuía uma fita infinita, dividida em células, e um cabeçote de &lt;strong&gt;leitura/escrita&lt;/strong&gt; que movia para frente e para trás na fita, possiblitando modificar o estado atual na máquina.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8hpp285hmrzc0txur45m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8hpp285hmrzc0txur45m.png" alt="turing machine"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Basicamente, este modelo de máquina permitiria que certas classes de problemas pudessem ser resolvidas com operações simples. &lt;/p&gt;

&lt;p&gt;Extrapolando, nesta fita, que pode representar um tipo de "memória", é possível armazenar o estado mas também outra máquina, ou seja, temos aqui o conceito de uma máquina de Turing universal, que é capaz de simular outra máquina de Turing.&lt;/p&gt;

&lt;p&gt;De forma resumida, podemos colocar na fita tanto o estado (dados) quanto as próprias instruções do programa, mitigando assim o problema de limitação que os computadores primitivos tinham, que era resolver problemas complexos de forma mais simples.&lt;/p&gt;

&lt;p&gt;Entretanto, a máquina de Turing era apenas uma abstração. Este conceito de instruções e estado na mesma memória precisava ser concretizado.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;É aí que entra von Neumann&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Arquitetura de von Neumann
&lt;/h3&gt;

&lt;p&gt;Von Neumman foi um polímata que propôs um modelo computacional que é utilizado por muitos computadores modernos e dispositivos que usamos hoje em dia.&lt;/p&gt;

&lt;p&gt;Neste modelo, temos uma unidade de processamento central, ou CPU, que é responsável por realizar cálculos aritméticos e executar instruções.&lt;/p&gt;

&lt;p&gt;Conectada a esta CPU, temos o conceito de &lt;em&gt;memória&lt;/em&gt; compartilhada, que vai ser usada para armazenar todas as instruções e estado de um programa de computador.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb0f759rhez1y6kinc7bf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb0f759rhez1y6kinc7bf.png" alt="von neumann 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Esta arquitetura possibilitou que computadores como ENIAC e EDVAC pudessem ser desenvolvidos. O EDVAC, por sua vez, foi um dos precursores na implementação do modelo de von Neumann, com uma CPU que era conectada a uma memória compartilhada e sequencial.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvmlzomad54zpeapwc2jv.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvmlzomad54zpeapwc2jv.jpeg" alt="edvac"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;À medida que os componentes computacionais foram ficando mais modernos, os computadores foram ficando menores, mais potentes, versáteis e com utilização de propósito mais geral. &lt;/p&gt;

&lt;p&gt;Então, a arquitetura de von Neumann pode ainda contar com dispositivos de entrada e saída de dados (impressora, teclado, mouse, placa de rede, monitor, etc), também conhecidos como dispositivos I/O:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffer0xexjvwrt4ooiwbjh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffer0xexjvwrt4ooiwbjh.png" alt="von neumann 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Podemos assumir, então, que quando escrevemos um programa de computador, estamos basicamente manipulando uma memória finita (que tem fim) e dispositivos de entrada e saída de dados, através de instruções que são executadas pela CPU.&lt;/p&gt;

&lt;p&gt;Tudo graças ao modelo concreto de von Neumann.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Vale destacar que há arquiteturas computacionais que não seguem este modelo, mas aqui neste guia estamos focando em computadores de propósito geral&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  O gargalo de von Neumann
&lt;/h3&gt;

&lt;p&gt;Esta arquitetura entretanto traz uma limitação. Como o barramento (caminho) entre a CPU e memória é único, tanto instruções quanto dados trafegam pelo mesmo local, levando a um cenário onde a CPU pode ficar limitada em processamento até que todos os dados sejam lidos do barramento.&lt;/p&gt;

&lt;p&gt;Uma forma de mitigar este problema é definir diferentes "níveis" de memória, para que a CPU possa ter uma taxa de processamento maior.&lt;/p&gt;

&lt;p&gt;Você acertou, vamos falar agora sobre a &lt;em&gt;hierarquia de memória&lt;/em&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Hierarquia de memória
&lt;/h2&gt;

&lt;p&gt;Nosso programa manipula memória. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Com que frequência? &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Todo tempo.&lt;/p&gt;

&lt;p&gt;Para mitigar o problema do gargalo de von Neumann, podemos definir uma hierarquia de memória, assim não só a memória principal (RAM) é "enxergada pela CPU" como memória, mas também outros dispositivos de armazenamento no sistema computacional.&lt;/p&gt;

&lt;p&gt;Adicionado a isso, com a modernização de computadores no século XX, foi criada a necessidade de orquestrar e controlar todas as interfaces com o hardware. Temos então a concepção de &lt;strong&gt;sistemas operacionais&lt;/strong&gt; para esta tarefa, que começam a surgir em meados dos anos 60/70, dentre eles o UNIX.&lt;/p&gt;

&lt;p&gt;Ao tratarmos tudo como memória, podemos introduzir tal &lt;strong&gt;hierarquia&lt;/strong&gt;. Portanto, num sistema computacional tratamos tudo (ou quase tudo) como memória e assim o sistema operacional (SO) pode abstrair de um determinado programa onde aquilo na hierarquia se encontra de fato sendo utilizado, deixando então nosso programa "livre" deste detalhe de implementação física.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi09gvyk1ext127w3u1mm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi09gvyk1ext127w3u1mm.png" alt="hierarquia memoria"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Quanto mais pro topo da hierarquia, menor a capacidade de armazenamento e mais caro. Por exemplo, registradores de  CPU são memórias voláteis que estão no topo.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Vamos falar sobre registradores mais a seguir na saga&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;E quanto mais pra base da hierarquia, maior a capacidade e consequentemente mais barato. Exemplo na base são as unidades de armazenamento durável não-voláteis (HD, SSD etc).&lt;/p&gt;

&lt;p&gt;No meio temos a memória principal e volátil, tendo como principal exemplo a memória RAM.&lt;/p&gt;

&lt;p&gt;A hierarquia de memória desempenha, então, um papel crucial na forma como a CPU gerencia e acessa memória.&lt;/p&gt;

&lt;h3&gt;
  
  
  Como a CPU executa instruções
&lt;/h3&gt;

&lt;p&gt;Para que uma CPU execute determinada instrução, é necessário ao menos um ciclo de clock, também chamado popularmente como "giro de CPU", ou &lt;em&gt;ciclo de CPU&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Vamos imaginar uma coisa que fica "girando" indefinidamente igual um relógio. De forma simples, é assim que podemos imaginar o clock de uma CPU, como um giro de relógio.&lt;/p&gt;

&lt;p&gt;Alguns tipos de instruções podem gastar mais de um ciclo, e determinar quais instruções vão gastar mais ou menos ciclos é algo que é projetado diretamente na &lt;strong&gt;construção da CPU&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;E onde as instruções ficam armazenadas? &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Isso mesmo, na memória.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Portanto, a CPU precisa buscar a instrução na memória, decodificar, executar e armazenar o resultado de volta na memória. &lt;/p&gt;

&lt;p&gt;Tudo isto faz gastar imensos ciclos de CPU. Ao gastarmos ciclos, a CPU pode bater num limite e não conseguir atender a tantas operações no mesmo segundo. Pra não mencionar a latência que a CPU gasta pra utilizar o barramento físico e "viajar" até a memória principal.&lt;/p&gt;

&lt;p&gt;Tomando como premissa a hierarquia de memória, e se ao invés de armazenar o resultado na memória principal, a CPU resolver armazenar dentro da própria CPU?&lt;/p&gt;

&lt;p&gt;Conheça os &lt;strong&gt;registradores de CPU&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Registradores de CPU
&lt;/h3&gt;

&lt;p&gt;Você já pode estar pensando em cache de CPU, né? Mas calma lá jovem, cache de CPU é outra seara que não pretendo entrar, não por agora.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Mas que também tem seu lugar na hierarquia de memória&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Lembrando (mais uma vez), da hierarquia de memória, de forma muito simplificada:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;topo: registradores&lt;/li&gt;
&lt;li&gt;depois: cache de CPU&lt;/li&gt;
&lt;li&gt;ainda depois: memória principal (RAM)&lt;/li&gt;
&lt;li&gt;beeem depois: memória secundária (HD, SSD)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Quanto mais perto do topo, mais rápido a CPU consegue processar, mas em contrapartida é volátil e também tem menor capacidade de armazenamento.&lt;/p&gt;

&lt;p&gt;Então, registradores são apenas memórias de hierarquia mais alta que são preferencialmente usadas para computação porque possuem a menor latência do conjunto de memórias disponíveis.&lt;/p&gt;

&lt;p&gt;São nos registradores onde a CPU vai armazenar instruções e dados do programa em execução, de modo a manipular sem precisar ficar dando tantos "saltos" na memória principal, economizando assim latência e ciclos de CPU.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1zzyclx72ff6nyr7b3ag.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1zzyclx72ff6nyr7b3ag.png" alt="von neumann - registradores"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vamos pensar nos registradores como "caixinhas" de tamanho fixo que ficam dentro da CPU. &lt;/p&gt;

&lt;p&gt;E como podemos manipular os registradores da CPU? Devemos estabelecer um padrão, que define como controlar o &lt;strong&gt;conjunto de instruções&lt;/strong&gt; da CPU.&lt;/p&gt;

&lt;p&gt;Precisamos de uma arquitetura de conjunto de instruções, ou &lt;strong&gt;ISA&lt;/strong&gt; (&lt;em&gt;Instruction Set Architecture&lt;/em&gt;).&lt;/p&gt;




&lt;h2&gt;
  
  
  ISA
&lt;/h2&gt;

&lt;p&gt;ISA serve para definir o conjunto instruções e registradores em uma determinada CPU. O fabricante define a ISA, que pode ser classificada de formas diferentes, determinando quantas operações podem ser feitas por instrução, entre outros aspectos.&lt;/p&gt;

&lt;p&gt;Neste artigo vamos destacar 2 abordagens de conjunto de instruções: &lt;em&gt;CISC e RISC&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  CISC
&lt;/h3&gt;

&lt;p&gt;CISC, ou &lt;strong&gt;Complex Instruction Set Computing&lt;/strong&gt;, é uma arquitetura onde as instruções podem ser agrupadas em conjuntos mais complexos de instruções, permitindo que uma única instrução execute várias operações complexas.&lt;/p&gt;

&lt;p&gt;Aqui, determinadas tarefas podem resultar em apenas um ciclo de CPU, o que aumenta eficiência, mas por outro lado, esta complexidade de instruções pode tornar o tempo de execução menos previsível.&lt;/p&gt;

&lt;p&gt;Exemplos de arquiteturas CISC incluem System/360, PDP-11 e Intel 8086.&lt;/p&gt;

&lt;h3&gt;
  
  
  RISC
&lt;/h3&gt;

&lt;p&gt;Para resolver o problema de instruções muito complexas em CISC, a arquiteura RISC, ou &lt;strong&gt;Reduced Instruction Set Computing&lt;/strong&gt;, determina uma execução mais simples com menos instruções, diminuindo assim o número de circuitos e consequentemente ciclos de CPU. O tamanho das instruções geralmente é fixo, resultando em um desempenho mais rápido e previsível.&lt;/p&gt;

&lt;p&gt;Exemplos de arquiteturas RISC são MIPS e ARM, sendo ARM atualmente utilizada nos processadores de MacBook M1 em diante.&lt;/p&gt;

&lt;p&gt;Este é um dos motivos de um MacBook ARM consumir menos bateria e fazer menos barulho, por exemplo.&lt;/p&gt;

&lt;h3&gt;
  
  
  E já que o tema é x86...
&lt;/h3&gt;

&lt;p&gt;Como a saga se trata de x86, especificamente 64-bit (logo mais vamos entender o motivo disso), inicialmente esta arquitetura foi desenvolvida seguindo o padrão CISC, que é o conjunto complexo de instruções.&lt;/p&gt;

&lt;p&gt;Entretanto a ISA do x86 foi adaptada para suportar internamente operações simplificadas como encontramos em RISC, portanto pode-se sizer que x86 é um "fake-CISC", que segue um modelo "RISC-ish".&lt;/p&gt;




&lt;h2&gt;
  
  
  Por quê x86?
&lt;/h2&gt;

&lt;p&gt;Alguns leitores mais atentos devem estar se perguntando: por quê raios x86? O que isto significa?&lt;/p&gt;

&lt;p&gt;Bom, pra entender o que é isto, vamos mergulhar um pouco na história dos microprocessadores da Intel.&lt;/p&gt;

&lt;h3&gt;
  
  
  Anos 70
&lt;/h3&gt;

&lt;p&gt;Os anos 70 foram primordiais. Além da explosão cambriana de sistemas operacionais, vemos também a consolidação da era dos transistores e assim a evolução das CPU's. &lt;/p&gt;

&lt;p&gt;Do lado Intel, temos o 8080 de 8-bit lançado em 1974, que além de ser utilizado em sistemas industriais, também foi amplamente encontrado nos primeiros computadores pessoais.&lt;/p&gt;

&lt;h3&gt;
  
  
  Intel 8086
&lt;/h3&gt;

&lt;p&gt;Esta versão traz consigo conjuntos de instruções de 16-bits e foi um marco na era dos computadores pessoais. É aqui que passa a ser cunhado o termo de família "x86", pois o "x" caracteriza qualquer número que venha antes de "86".&lt;/p&gt;

&lt;p&gt;Intuitivo, não?&lt;/p&gt;

&lt;h3&gt;
  
  
  Anos 80, a década do Intel x86
&lt;/h3&gt;

&lt;p&gt;A partir de então, nesta década vimos a chegada do 80286 (286) que suporta também 16-bit + 8-bit de endereçamento de memória; depois, o famoso 80386 (i386), que trouxe uma grande mudança suportando instruções de 32-bit e os famosos registradores &lt;code&gt;exx&lt;/code&gt; (eax, ebx, eip, etc); para então chegarmos ao 80486 (486), que foi uma melhoria do 386 com suporte a instruções mais avançadas.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pra quem tiver curiosidade em saber a especificação da arquitetura x86, está tudo bem documentado num simples &lt;a href="https://software.intel.com/en-us/download/intel-64-and-ia-32-architectures-sdm-combined-volumes-1-2a-2b-2c-2d-3a-3b-3c-3d-and-4" rel="noopener noreferrer"&gt;manual de 5000 páginas&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Anos 90, Pentium e além
&lt;/h3&gt;

&lt;p&gt;O que vem a seguir é a evolução seguindo com os Pentium 586, 686 e depois, uma simplificação dos termos para x86_32 (32-bit) ou x86_64 (64-bit).&lt;/p&gt;

&lt;p&gt;Destaca-se os Pentium II, III e os Core "i AlgumaCoisa" que perduram até hoje.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;E os AMD?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Enquanto a Intel dominava o mercado de CPU's, a AMD (Advanced Micro Devices) mexeu os palitinhos e também lançou versões compatíveis com x86, portanto pode-se dizer que, ao desenvolver para arquitetura x86, é possível executar as mesmas instruções em uma CPU fabricada pela AMD.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;É isto. Este foi um artigo bastante denso, que cobriu uma breve história dos computadores, passando por modelos computacionais até chegar nas arquiteturas de CPU's e entendermos o que significa aquele "x86" no título do artigo.&lt;/p&gt;

&lt;p&gt;No próximo artigo, pretendo trazer brevemente sistema binário e hexadecimal para então começar a apresentar aquilo que estamos todos interessados: linguagem de montagem, ou simplesmente &lt;strong&gt;Assembly&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Artigo revisado com carinho por &lt;a href="https://twitter.com/JeffQuesado" rel="noopener noreferrer"&gt;Jeff Quesado&lt;/a&gt;, o "Coelho da Bolha", e também por &lt;a href="https://twitter.com/_____cadu_____" rel="noopener noreferrer"&gt;Cadu&lt;/a&gt;, o músico frustrado (same thing).&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;p&gt;&lt;br&gt;
Ábaco, Wikipedia&lt;br&gt;
&lt;a href="https://pt.wikipedia.org/wiki/%C3%81baco" rel="noopener noreferrer"&gt;https://pt.wikipedia.org/wiki/%C3%81baco&lt;/a&gt;&lt;br&gt;
Máquina analítica, Wikipedia&lt;br&gt;
&lt;a href="https://pt.wikipedia.org/wiki/M%C3%A1quina_anal%C3%ADtica" rel="noopener noreferrer"&gt;https://pt.wikipedia.org/wiki/M%C3%A1quina_anal%C3%ADtica&lt;/a&gt;&lt;br&gt;
Linguagem Assembly, Wikipedia&lt;br&gt;
&lt;a href="https://pt.wikipedia.org/wiki/Linguagem_assembly" rel="noopener noreferrer"&gt;https://pt.wikipedia.org/wiki/Linguagem_assembly&lt;/a&gt;&lt;br&gt;
Cronologia do x86, Wikipedia&lt;br&gt;
&lt;a href="https://pt.wikipedia.org/wiki/X86" rel="noopener noreferrer"&gt;https://pt.wikipedia.org/wiki/X86&lt;/a&gt;&lt;br&gt;
Arquitetura de Von Neumann, Wikipedia&lt;br&gt;
&lt;a href="https://pt.wikipedia.org/wiki/Arquitetura_de_von_Neumann" rel="noopener noreferrer"&gt;https://pt.wikipedia.org/wiki/Arquitetura_de_von_Neumann&lt;/a&gt;&lt;br&gt;
Blau Araujo, "Fundamentos de Assembly com NASM"&lt;br&gt;
&lt;a href="https://codeberg.org/blau_araujo/assembly-nasm-x86_64" rel="noopener noreferrer"&gt;https://codeberg.org/blau_araujo/assembly-nasm-x86_64&lt;/a&gt;&lt;br&gt;
História da Computação, Wikipedia&lt;br&gt;
&lt;a href="https://pt.wikipedia.org/wiki/Hist%C3%B3ria_da_computa%C3%A7%C3%A3o" rel="noopener noreferrer"&gt;https://pt.wikipedia.org/wiki/Hist%C3%B3ria_da_computa%C3%A7%C3%A3o&lt;/a&gt;&lt;br&gt;
Inifitamente, "Como reinventar um computador do zero"&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=BbnDmeNojFA" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=BbnDmeNojFA&lt;/a&gt;&lt;br&gt;
Total Phase, "What's a CPU register"&lt;br&gt;
&lt;a href="https://www.totalphase.com/blog/2023/05/what-is-register-in-cpu-how-does-it-work/" rel="noopener noreferrer"&gt;https://www.totalphase.com/blog/2023/05/what-is-register-in-cpu-how-does-it-work/&lt;/a&gt;&lt;br&gt;
Turing Machine, Wikipedia&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Turing_machine" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Turing_machine&lt;/a&gt;&lt;br&gt;
Brilliant, "Turing Machines"&lt;br&gt;
&lt;a href="https://brilliant.org/wiki/turing-machines/" rel="noopener noreferrer"&gt;https://brilliant.org/wiki/turing-machines/&lt;/a&gt;&lt;br&gt;
Instruction Set Architecture, Wikipedia&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Instruction_set_architecture" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Instruction_set_architecture&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

</description>
      <category>assembly</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Construindo um web server em Assembly x86, parte I, introdução</title>
      <dc:creator>Leandro Proença</dc:creator>
      <pubDate>Tue, 09 Apr 2024 03:51:43 +0000</pubDate>
      <link>https://dev.to/leandronsp/construindo-um-web-server-em-assembly-x86-parte-i-introducao-14p5</link>
      <guid>https://dev.to/leandronsp/construindo-um-web-server-em-assembly-x86-parte-i-introducao-14p5</guid>
      <description>&lt;p&gt;&lt;em&gt;Assembly&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Para alguns, um monstrinho. Pra outros, algo antiquado. Mas pra quem tem curiosidade em entender como as coisas funcionam, &lt;strong&gt;oportunidade&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Nesta saga que será uma série de artigos, vamos explorar Assembly com NASM para arquitetura &lt;em&gt;x86-64&lt;/em&gt; em GNU/Linux enquanto desenvolvemos um web server multi-thread bastante simples.&lt;/p&gt;

&lt;p&gt;O intuito não está nas capacidades do web server em si, pois este irá apenas responder uma mensagem "Hello, world" em formato HTML, mas sim nos conceitos utilizados para construi-lo.&lt;/p&gt;

&lt;p&gt;Para quem não tem muita familiaridade com conceitos de mais baixo-nível em computação e concorrência, não se preocupe, pois queremos com este guia fazer com que temas que são vistos como "complexos" possam ser absorvidos com mais facilidade a quem tem curiosidade, podendo então causar aquela boa impressão no churrasco de domingo ou no jantar de Natal.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To brincando gente, tá proibido falar de Assembly nestas ocasiões, por favor não façam isso eu imploro&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Conteúdo proposto
&lt;/h2&gt;

&lt;p&gt;Ao longo dos artigos vamos passar por diversos conceitos de computação, sendo alguns de forma superficial e outros com um pouco mais de profundidade, podendo mencionar alguns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Arquitetura de computadores&lt;/li&gt;
&lt;li&gt;Tipos de arquiteturas&lt;/li&gt;
&lt;li&gt;Padrões, sistema binário e hexadecimal&lt;/li&gt;
&lt;li&gt;Básicos de Assembly x86-64&lt;/li&gt;
&lt;li&gt;Debugging com GDB&lt;/li&gt;
&lt;li&gt;Filesystem, Sockets&lt;/li&gt;
&lt;li&gt;Threads, pool e alocação de memória&lt;/li&gt;
&lt;li&gt;Arrays, filas, ponteiros&lt;/li&gt;
&lt;li&gt;Concorrência e primitivos de sincronização como spinlocks e futex&lt;/li&gt;
&lt;li&gt;Tag &lt;code&gt;h1&lt;/code&gt; do HTML (LOL)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Poderá haver mais conceitos a serem abordados, mas que serão mapeados e detalhados conforme necessidade.&lt;/p&gt;




&lt;h2&gt;
  
  
  É um tutorial de Assembly?
&lt;/h2&gt;

&lt;p&gt;Definitivamente, não. &lt;/p&gt;

&lt;p&gt;A ideia aqui é desenvolver de forma prática um servidor web enquanto passamos por conceitos de Assembly e não só, mas também outros temas importantes sobre concorrência.&lt;/p&gt;

&lt;p&gt;Se quer fazer um tutorial rápido para se familiarizar com Assembly x86, há &lt;a href="https://www.tutorialspoint.com/assembly_programming/index.htm"&gt;este do tutorials point&lt;/a&gt;, mas atenção que ele é para 32-bits, sendo que nosso guia será feito em 64-bits (uma vez entendido os conceitos, fica fácil transportar).&lt;/p&gt;




&lt;h2&gt;
  
  
  É um curso de Assembly?
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Hell no&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Obviamente, vamos aprender diversos conceitos à medida que avançamos na saga, mas se você tem algum interesse em aprender fundamentos de Assembly de forma bastante didática, sugiro acompanhar a playlist de &lt;a href="https://www.youtube.com/live/Ej6U-qk0bdE?feature=shared"&gt;Fundamentos de Assembly x86-64&lt;/a&gt; do Blau Araújo. Ele é referência no assunto em conteúdo pt-BR e já cortou muito mato neste assunto.&lt;/p&gt;




&lt;h2&gt;
  
  
  Requisitos de ambiente
&lt;/h2&gt;

&lt;p&gt;É esperado que o código seja executado em um sistema UNIX-based, preferencialmente GNU/Linux x86_64 que é onde testamos o código proposto. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sistema Operacional Ubuntu 22.04.4 LTS (GNU/Linux 6.5.0-17-generic x86_64)&lt;/li&gt;
&lt;li&gt;NASM 2.16.01&lt;/li&gt;
&lt;li&gt;GNU ld 2.38 (binutils)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;E para debugging (claro, nesta casa fazemos debugging, não somos brincalhões):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GNU gdb 12.1&lt;/li&gt;
&lt;li&gt;strace 5.16&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para outros ambientes, pode-se optar por rodar o código dentro de um container Docker, seguindo as versões acima apresentadas. &lt;/p&gt;

&lt;p&gt;Exemplo de &lt;strong&gt;Dockerfile&lt;/strong&gt; (validar isto plmdds):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;FROM ubuntu
RUN apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="nb"&gt;install &lt;/span&gt;make binutils gdb build-essential wget strace
WORKDIR /app
RUN wget https://www.nasm.us/pub/nasm/releasebuilds/2.16.01/nasm-2.16.01.tar.gz &lt;span class="nt"&gt;-O&lt;/span&gt; nasm.tar.gz &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-xzvf&lt;/span&gt; nasm.tar.gz &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;nasm-2.16.01 &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; ./configure &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; make &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; make &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Será que consigo acompanhar?
&lt;/h2&gt;

&lt;p&gt;Você pode apenas ler e tentar entender os conceitos, ou então ser mais hands-on e escrever código à medida que avança nos artigos. &lt;/p&gt;

&lt;p&gt;Recomendo fortemente que experimente o código e rode em seu próprio computador seguindo os requisitos de ambiente, seja em host, virtualizado ou containerizado.&lt;/p&gt;

&lt;p&gt;O repositório com o código completo pode ser encontrado em &lt;a href="https://github.com/leandronsp/magali"&gt;leandronsp/magali&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Este artigo é o primeiro de uma série que vamos explorar sobre Assembly x86-64 enquanto desenvolvemos um web server do zero, sem enrolação e com muita mão na massa.&lt;/p&gt;

&lt;p&gt;No próximo artigo já iremos começar com introdução a arquiteturas de computadores e o básico necessário com as terminologias e um pouco de história dos computadores, padrões e linguagens Assembly.&lt;/p&gt;

&lt;p&gt;Stay tuned!&lt;/p&gt;

</description>
      <category>assembly</category>
      <category>braziliandevs</category>
    </item>
  </channel>
</rss>
