An assembly code is written in a file with suffix .s and looks like this:
.text .globl main main: ... mov $0, %rax # exit code ret .data ...You can compile and run such a program as follows:
gcc -g file.s -o file ./file(Add the option -no-pie if you use gcc version 5 or later.)
When needed, you can use gdb (installed in salles info) to execute your program step by step. Use the following commands
gdb ./file (gdb) break main (gdb) runand then execute one step with command step. More information in this tutorial.
This page by Andrew Tolmach provides some information to write / debug x86-64 assembly code. These notes on x86-64 programming are really useful.
#include <stdio.h> int main() { printf("n = %d\n", 42); return 0; }To call the library function printf, we pass its first argument (the format string) in register %rdi and its second argument (here the integer 42) in register %rsi, as specified by the calling conventions. We must also set register %rax to zero before calling printf, since it is a variadic function (in that case, %rax indicates the number of arguments passed in vector registers --- here none).
The format string must be declared in the data segment (.data) using the directive .string that adds a trailing 0-character.
#include <stdio.h> int isqrt(int n) { int c = 0, s = 1; while (s <= n) { c++; s += 2*c + 1; } return c; } int main() { int n; for (n = 0; n <= 20; n++) printf("sqrt(%2d) = %2d\n", n, isqrt(n)); return 0; }Try to do the following:
The C program matrix.c contains a solution, to be read carefully. This solution uses two main ingredients:
const int m[N][N] = { { 7, 53, ..., 583 }, { 627, 343, ... }, ... };In the memory layout, integers are stored consecutively, by rows. Each integer is stored on 32 bits and thus the matrix m uses 900 bytes in total. The integer m[i][j] is located at address m + 4 * (15*i + j).
We provide a file matrix.s that contains static data for the matrix m, as well as space for the array memo. The latter is initialized with zeros, and thus can be allocated in section .bss so that it does not increase the size of the executable unnecessarily.
Be careful: to compute 1 << j, one must do a shift whose size is not a constant. To do so, the operand of instruction sal, which is j here, must be placed in the byte register %cl. For this reason, it is a good idea to allocate variable j in register %rcx.