Leetcoding in Assembly — Challenge Accepted

David De
5 min readApr 24, 2024

--

Assembly Language Icon. Found at https://thenounproject.com/icon/asm-762420/

I saw this video on Youtube the other day, where Low Level Learning used Assembly to solve a Leetcode problem. I decided to take the challenge up to solve at-least 10 leetcode problems using Assembly.

First of all, as he says in the video there is no Assembly option in Leetcode, so we need to improvise. I will do what he basically did, that is use Inline Assembly in C.

Also, I will not be using Intel Syntax, instead I am more comfortable using the AT&T version so I will do that.

The other thing that I will also change is, I will use Extended Assembly instead of Assembly.

Here are the 10 problems, these from the Array, Strings, Dynamic Programming problems.

1108. Defanging an IP Address

#include <stdio.h>
#include <string.h>

char * defangIPaddr(char * address){
int len_of_orig = strlen(address);

int len_of_new = strlen(address) + 7;
char* res = malloc(sizeof(char) * len_of_new);
res[len_of_new - 1] = '\0';

__asm__ __volatile__ (
"xor %%rcx, %%rcx;"
"xor %%rdx, %%rdx;"
"xor %%r9, %%r9;"

"mov $0, %%rcx;" // i the index for address
"mov $0, %%rdx;" // j the index for res

"loop%=:;"
"cmpl %1, %%ecx;"
"je end%=;"

"movb (%2, %%rcx, 1), %%r9b;"
"cmpb $46, %%r9b;"
"je is_dot%=;"

"movb %%r9b, (%0, %%rdx, 1);"
"inc %%rdx;"

"jmp continue_loop%=;"

"continue_loop%=:;"
"inc %%rcx;"
"jmp loop%=;"

"is_dot%=:;"
"movb $91, (%0, %%rdx, 1);"
"inc %%rdx;"
"movb $46, (%0, %%rdx, 1);"
"inc %%rdx;"
"movb $93, (%0, %%rdx, 1);"
"inc %%rdx;"

"jmp continue_loop%=;"

"end%=:;"
: "+r" (res)
: "r" (len_of_orig), "r" (address)
);



return res;
}

1137. N-th Tribonacci Number

int tribonacci(int n){
int res = 0;

__asm__ __volatile__ (
"cmpl $0, %1;"
"je end_early_0%=;"

"cmp $1, %1;"
"je end_early_1%=;"

"movl $0, %%eax;"
"movl $1, %%ecx;"
"movl $1, %%edx;"

"movl $2, %%r8d;"

"loop%=:;"
"cmpl %%r8d, %1;"
"je end%=;"

"movl $0, %%r9d;"

"addl %%eax, %%r9d;"
"addl %%ecx, %%r9d;"
"addl %%edx, %%r9d;"

"movl %%ecx, %%eax;"
"movl %%edx, %%ecx;"
"movl %%r9d, %%edx;"

"incl %%r8d;"
"jmp loop%=;"

"end%=:;"
"movl %%edx, %0;"
"jmp last%=;"

"end_early_0%=:;"
"movl $0, %0;"
"jmp last%=;"

"end_early_1%=:;"
"movl $1, %0;"
"jmp last%=;"

"last%=:"
: "+r" (res)
: "r" (n)
);

return res;
}

771. Jewels and Stones

#include <string.h>

int numJewelsInStones(char* jewels, char* stones) {
int res = -0;

int len_of_jewels = strlen(jewels);
int len_of_stones = strlen(stones);

__asm__ __volatile__ (
"xor %%rax, %%rax;"

"xor %%rcx, %%rcx;"
"xor %%rdx, %%rdx;"

"xor %%r9, %%r9;"
"xor %%r10, %%r10;"

"loop_i%=:;"
"cmpl %%ecx, %1;"
"je end_loop_i%=;"

"movb (%2, %%rcx, 1), %%r9b;"
"inc %%rcx;"

"loop_j%=:;"
"cmpl %%edx, %3;"
"je end_loop_j%=;"

"movb (%4, %%rdx, 1), %%r10b;"
"inc %%rdx;"

"cmpb %%r9b, %%r10b;"
"je add_to_result%=;"

"jmp loop_j%=;"

"add_to_result%=:;"
"incl %%eax;"
"jmp loop_j%=;"

"end_loop_j%=:;"
"movl $0, %%edx;"
"jmp loop_i%=;"

"end_loop_i%=:;"
"movl %%eax, %0;"
: "+r" (res)
: "r" (len_of_jewels), "r" (jewels), "r" (len_of_stones), "r" (stones)
);

return res;
}

70. Climbing Stairs


__attribute__((naked))
int climbStairs(int n) {
__asm__(
"movl $1, %eax;" // pre_pre = 1
"movl $1, %ecx;" // pre = 1
"movl $2, %edx;" // res = 2

"loop:;" // while res > n
"cmpl %edi, %edx;"
"jg end;"

"movl %eax, %esi;" // tmp = pre_pre
"addl %ecx, %esi;" // tmp += pre
"movl %eax, %ecx;" // pre_pre = pre
"movl %esi, %eax;" // pre = tmp

"incl %edx;"
"jmp loop;"

"end:;"
"ret;"
);
}

509. Fibonacci Number


__attribute__((naked))
int fib(int n){
__asm__(
"cmpl $0, %edi;" // if EDI == 0 {
"je end_immediate;"

"movl $0, %ecx;" // ECX = 0; pre
"movl $1, %eax;" // EAX = 1; Res
"movl $2, %edx;" // EDX = 2; n

"loop:;"
"cmpl %edi, %edx;" // EDI = n
"jg end;" // while ebx <= edi {

"movl %eax, %esi;" // ESI = EAX; temp
"addl %ecx, %esi;" // ESI += ECX; temp
"movl %eax, %ecx;" // ECX = EAX; pre
"movl %esi, %eax;" // EAX = ESI; res

"incl %edx;"
"jmp loop;"
"end:;"
"ret;"
"end_immediate:;"
"movl $0, %eax;" // EAX = 0; res
"ret;"
);
}

1470. Shuffle the Array



/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* shuffle(int* nums, int numsSize, int n, int* returnSize){
int* res = malloc(sizeof(int) * numsSize);

__asm__ __volatile__(

"movl $0, %%r8d;"
"movl %%edx, %%r9d;"
"mov $0, %%r10;"

"loop_i%=:;"
"cmpl %%edx, %%r8d;"
"je end_loop_i%=;"

"movl (%%rcx, %%r8, 4), %%esi;"
"movl %%esi, (%%rax, %%r10, 4);"
"inc %%r10;"

"movl (%%rcx, %%r9, 4), %%esi;"
"movl %%esi, (%%rax, %%r10, 4);"
"inc %%r10;"

"inc %%r8d;"
"inc %%r9d;"
"jmp loop_i%=;"

"end_loop_i%=:;"
: "=a" (res)
: "a" (res), "c" (nums), "d" (n)
: "r8", "r9", "r10", "memory"
);

*returnSize = numsSize;
return res;
}

2798. Number of Employees Who Met the Target

int numberOfEmployeesWhoMetTarget(int* hours, int hoursSize, int target){
int res = 0;

__asm__ __volatile__ (
"mov $0, %%r8d;"
"movl $0, %%eax;"

"loop%=:;"
"cmpl %%r8d, %2;"
"je end%=;"

"movl (%1, %%r8, 4), %%r9d;"
"inc %%r8;"

"cmpl %3, %%r9d;"
"jge accumulate%=;"

"jmp loop%=;"

"accumulate%=:;"
"incl %%eax;"
"jmp loop%=;"

"end%=:;"
"movl %%eax, %0;"
: "=r" (res)
: "r" (hours), "r" (hoursSize), "r" (target)
: "r8", "r9", "memory", "eax"
);

return res;
}

3110. Score of a String

int scoreOfString(char* s) {
int res = 0;

__asm__ __volatile__(
"mov $0, %%rax;"

"mov %%rcx, %%r8;"
"mov $0, %%r11;"

"loop%=:;"
"movb 1(%%r8), %%r9b;"

"cmpb $0, %%r9b;"
"je end%=;"

"movb (%%r8), %%r10b;"

"subb $97, %%r9b;"
"subb $97, %%r10b;"

"cmpb %%r10b, %%r9b;"
"jg go_to_10_g_9%=;"

"subl %%r9d, %%r10d;"

"addl %%r10d, %%r11d;"

"inc %%r8;"
"jmp loop%=;"

"go_to_10_g_9%=:;"

"subl %%r10d, %%r9d;"

"addl %%r9d, %%r11d;"

"inc %%r8;"
"jmp loop%=;"

"end%=:;"
"movl %%r11d, %%eax;"
: "+a" (res)
: "c" (s)
: "r8", "r9", "r10", "r11", "memory"
);

return res;
}

121. Best Time to Buy and Sell Stock



int maxProfit(int* prices, int pricesSize) {
int res = 0;

__asm__ __volatile__(
"mov $0, %%r8;"

"mov (%%rcx), %%r10d;"
"mov $0, %%r11;"

"loop_i%=:;"
"cmpl %%edx, %%r8d;"
"je end%=;"

"movl (%%rcx, %%r8, 4), %%esi;"
"inc %%r8;"

"cmpl %%r10d, %%esi;"
"jl min_price_so_far%=;"

"max_profit_so_far%=:;"
"subl %%r10d, %%esi;"
"cmpl %%r11d, %%esi;"
"jg note_max%=;"

"jmp loop_i%=;"

"min_price_so_far%=:;"
"movl %%esi, %%r10d;"
"jmp max_profit_so_far%=;"

"note_max%=:;"
"movl %%esi, %%r11d;"
"jmp loop_i%=;"


"end%=:;"
"movl %%r11d, %%eax;"
: "=a" (res)
: "c" (prices), "d" (pricesSize)
: "r8", "r9", "r10", "r11", "esi", "edi", "memory"
);

return res;
}

1929. Concatenation of Array

/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* getConcatenation(int* nums, int numsSize, int* returnSize) {
int* res = malloc(sizeof(int) * 2 * numsSize);

__asm__ __volatile__ (
"mov $0, %%r8;"
"mov $0, %%r9;"
"movl %%edx, %%r10d;"

"loop%=:;"
"cmpl %%r8d, %%edx;"
"je end_loop_first%=;"

"movl (%%rcx, %%r8, 4), %%r11d;"
"inc %%r8;"

"movl %%r11d, (%%rax, %%r9, 4);"
"inc %%r9;"

"movl %%r11d, (%%rax, %%r10, 4);"
"inc %%r10;"

"jmp loop%=;"

"end_loop_first%=:;"
: "+a" (res)
: "c" (nums), "d" (numsSize)
: "r8", "r9", "r10", "r11"
);

*returnSize = 2 * numsSize;
return res;
}

Conclusion

Leetcode is a great place to hone your programming skills in almost any programming language possible. If you want to see the video from Low Level Learning, here you go:

More things you might be interested in

Leetcoding in Rust

Coding

System Design

--

--

David De
David De

No responses yet