define(w_multiplier, w19) // Define a macro to store multiplier define(w_multiplicand, w20) // Define a macro to store multiplicand define(w_product, w21) // Define a macro to store product define(w_i, w22) // Define a macro to store i (loop counter) define(w_negative, w23) // Define a macro to store negative flag (0 or 1) define(x_result, x19) // Define a macro to store result define(x_temp1, x20) // Define a macro to store temp1 define(x_temp2, x21) // Define a macro to store temp2 fmt1: .string "multiplier = 0x%08x (%d) multiplicand = 0x%08x (%d)\n\n" // initial values of variables print string fmt2: .string "product = 0x%08x multiplier = 0x%08x\n" // product and multiplier print string fmt3: .string "64-bit result = 0x%016lx (%ld)\n" // 64-bit result print string .balign 4 .global main main: stp x29, x30, [sp, -16]! // allocate stack space mov x29, sp // Update fp mov w_multiplicand, -16843010 // Initialize multiplicand to -16843010 mov w_multiplier, 70 // Initialize multiplier to 70 mov w_product, 0 // Initialize product to 0 mov w_negative, 0 // Initialize negative to 0 (FALSE) mov w_i, 0 adrp x0, fmt1 // Add fmt1 to x0 add x0, x0, :lo12:fmt1 // Format string mov w1, w_multiplier // Set first parameter mov w2, w_multiplier // Set second parameter mov w3, w_multiplicand // Set third parameter mov w4, w_multiplicand // Set fourth parameter bl printf // Call printf function cmp w_multiplier, 0 // Compare multiplier to 0 b.ge top // If multiplier is > 0, branch to test mov w_negative, 1 // Otherwise set negative to 1 (TRUE) b test // Branch to test top: tst w_multiplier, 0x1 // Perform an ands to eval multiplier with 0x1 b.eq top2 // Branch to top1 on equal (Z flag == 1) add w_product, w_product, w_multiplicand // Perform inner if by adding product + multiplicand top2: asr w_multiplier, w_multiplier, 1 // Arithmetic shift right the combined product and multiplier tst w_product, 0x1 // if (product & 0x1) b.ne inner_if2 // Branch on not equal to inner_else and w_multiplier, w_multiplier, 0x7FFFFFFF // else, b top3 inner_if2: orr w_multiplier, w_multiplier, 0x80000000 // Perform inclusive OR and store value in multiplier top3: asr w_product, w_product, 1 // Arithmetic shift right add w_i, w_i, 1 // Increment loop counter test: cmp w_i, 32 // Compare i to 32 b.lt top // If i is less-than 32, branch to top cmp w_negative, 0 // Compare negative to 0 ==> if(negative) b.eq final // Breanch on equal to final sub w_product, w_product, w_multiplicand // Adjust product register if multiplier is negative final: adrp x0, fmt2 // Add fmt2 to x0 add x0, x0, :lo12:fmt2 // Format string mov w1, w_product // Add product to parameter 1 mov w2, w_multiplier // Add multiplier to parameter 2 bl printf // Call printf function sxtw x_temp1, w_product // Sign extend the 32-bit product to 64-bit and store in temp1 and x_temp1, x_temp1, 0xFFFFFFFF // Perform AND with product and hex value lsl x_temp1, x_temp1, 32 // Perform logical left shift on temp1 sxtw x_temp2, w_multiplier // Sign extend the 32-bit multiplier to 64-bit and store in temp2 and x_temp2, x_temp2, 0xFFFFFFFF // Perform AND with multiplier and hex value add x_result, x_temp1, x_temp2 // Add the results of both ANDS and store in 64-bit result register adrp x0, fmt3 // Add fmt3 to x0 add x0, x0, :lo12:fmt3 // Format string mov x1, x_result // Add result in parameter 1 mov x2, x_result // Add result in parameter 2 bl printf // Call printf function done: mov w0, 0 // set return value to 0 ldp x29, x30, [sp], 16 // restore stack ret // return control to OS
Write, Run & Share Assembly code online using OneCompiler's Assembly online compiler for free. It's one of the robust, feature-rich online compilers for Assembly language. Getting started with the OneCompiler's Assembly compiler is simple and pretty fast. The editor shows sample boilerplate code when you choose language as Assembly
and start coding.
Assembly language(asm) is a low-level programming language, where the language instructions will be more similar to machine code instructions.
Every assembler may have it's own assembly language designed for a specific computers or an operating system.
Assembly language requires less execution time and memory. It is more helful for direct hardware manipulation, real-time critical applications. It is used in device drivers, low-level embedded systems etc.
Assembly language usually consists of three sections,
Data section
To initialize variables and constants, buffer size these values doesn't change at runtime.
bss section
To declare variables
text section
_start
specifies the starting of this section where the actually code is written.
There are various define directives to allocate space for variables for both initialized and uninitialized data.
variable-name define-directive initial-value
Define Directive | Description | Allocated Space |
---|---|---|
DB | Define Byte | 1 byte |
DW | Define Word | 2 bytes |
DD | Define Doubleword | 4 bytes |
DQ | Define Quadword | 8 bytes |
DT | Define Ten Bytes | 10 bytes |
Define Directive | Description |
---|---|
RESB | Reserve a Byte |
RESW | Reserve a Word |
RESD | Reserve a Doubleword |
RESQ | Reserve a Quadword |
REST | Reserve a Ten Bytes |
Constants can be defined using
CONSTANT_NAME EQU regular-exp or value
%assign constant_name value
%define constant_name value
Loops are used to iterate a set of statements for a specific number of times.
mov ECX,n
L1:
;<loop body>
loop L1
where n specifies the no of times loops should iterate.
Procedure is a sub-routine which contains set of statements. Usually procedures are written when multiple calls are required to same set of statements which increases re-usuability and modularity.
procedure_name:
;procedure body
ret