Introduction to 8086 Assembly

Similar documents
Credits and Disclaimers

Credits and Disclaimers

x86 assembly CS449 Spring 2016

X86 Addressing Modes Chapter 3" Review: Instructions to Recognize"

CS Bootcamp x86-64 Autumn 2015

Lecture 15 Intel Manual, Vol. 1, Chapter 3. Fri, Mar 6, Hampden-Sydney College. The x86 Architecture. Robb T. Koether. Overview of the x86

CS241 Computer Organization Spring 2015 IA

Assembly Language Each statement in an assembly language program consists of four parts or fields.

x86 Assembly Crash Course Don Porter

CS 31: Intro to Systems ISAs and Assembly. Martin Gagné Swarthmore College February 7, 2017

The x86 Architecture

Access. Young W. Lim Sat. Young W. Lim Access Sat 1 / 19

CSC 2400: Computer Systems. Towards the Hardware: Machine-Level Representation of Programs

Access. Young W. Lim Fri. Young W. Lim Access Fri 1 / 18

MODE (mod) FIELD CODES. mod MEMORY MODE: 8-BIT DISPLACEMENT MEMORY MODE: 16- OR 32- BIT DISPLACEMENT REGISTER MODE

Turning C into Object Code Code in files p1.c p2.c Compile with command: gcc -O p1.c p2.c -o p Use optimizations (-O) Put resulting binary in file p

UMBC. A register, an immediate or a memory address holding the values on. Stores a symbolic name for the memory location that it represents.

CSC 8400: Computer Systems. Machine-Level Representation of Programs

Assembly level Programming. 198:211 Computer Architecture. (recall) Von Neumann Architecture. Simplified hardware view. Lecture 10 Fall 2012

x86 assembly CS449 Fall 2017

x86 architecture et similia

Registers. Ray Seyfarth. September 8, Bit Intel Assembly Language c 2011 Ray Seyfarth

CS165 Computer Security. Understanding low-level program execution Oct 1 st, 2015

W4118: PC Hardware and x86. Junfeng Yang

CSCI 192 Engineering Programming 2. Assembly Language

Assembly Language: IA-32 Instructions

CMSC Lecture 03. UMBC, CMSC313, Richard Chang

Putting the pieces together

Binghamton University. CS-220 Spring x86 Assembler. Computer Systems: Sections

MACHINE-LEVEL PROGRAMMING I: BASICS COMPUTER ARCHITECTURE AND ORGANIZATION

Instruction Set Architectures

4) C = 96 * B 5) 1 and 3 only 6) 2 and 4 only

CMSC 313 Lecture 12 [draft] How C functions pass parameters

CS 31: Intro to Systems ISAs and Assembly. Kevin Webb Swarthmore College February 9, 2016

Instruction Set Architectures

CS 31: Intro to Systems ISAs and Assembly. Kevin Webb Swarthmore College September 25, 2018

Intro to GNU Assembly Language on Intel Processors

Assembly Language: Function Calls

X86 Review Process Layout, ISA, etc. CS642: Computer Security. Drew Davidson

System calls and assembler

Assembly Language: Function Calls" Goals of this Lecture"

Reverse Engineering II: Basics. Gergely Erdélyi Senior Antivirus Researcher

Introduction to Intel x86-64 Assembly, Architecture, Applications, & Alliteration. Xeno Kovah 2014 xkovah at gmail

Reverse Engineering II: The Basics

Assembly Language: Function Calls" Goals of this Lecture"

CMSC 313 Lecture 12. Project 3 Questions. How C functions pass parameters. UMBC, CMSC313, Richard Chang

Interfacing Compiler and Hardware. Computer Systems Architecture. Processor Types And Instruction Sets. What Instructions Should A Processor Offer?

Assembly Language: Function Calls. Goals of this Lecture. Function Call Problems

mith College Computer Science CSC231 - Assembly Week #4 Dominique Thiébaut

GCC and Assembly language. GCC and Assembly language. Consider an example (dangeous) foo.s

CS642: Computer Security

EEM336 Microprocessors I. Addressing Modes

CMSC 313 COMPUTER ORGANIZATION & ASSEMBLY LANGUAGE PROGRAMMING LECTURE 03, SPRING 2013

The von Neumann Machine

6/20/2011. Introduction. Chapter Objectives Upon completion of this chapter, you will be able to:

Compiler Construction D7011E

Assembly Programmer s View Lecture 4A Machine-Level Programming I: Introduction

Assembly I: Basic Operations. Jin-Soo Kim Computer Systems Laboratory Sungkyunkwan University

x86 Programming I CSE 351 Winter

Software. Hardware. x86 basics. ISA View. a brief history of x86 10/6/15. Program, Application. Programming Language. Compiler/Interpreter

Today: Machine Programming I: Basics

administrivia today start assembly probably won t finish all these slides Assignment 4 due tomorrow any questions?

AS08-C++ and Assembly Calling and Returning. CS220 Logic Design AS08-C++ and Assembly. AS08-C++ and Assembly Calling Conventions

Meet & Greet! Come hang out with your TAs and Fellow Students (& eat free insomnia cookies) When : TODAY!! 5-6 pm Where : 3rd Floor Atrium, CIT

How Software Executes

CSE2421 FINAL EXAM SPRING Name KEY. Instructions: Signature

LAB 5 Arithmetic Operations Simple Calculator

Process Layout and Function Calls

Machine Program: Procedure. Zhaoguo Wang

Machine-Level Programming Introduction

CS241 Computer Organization Spring Introduction to Assembly

Machine Programming 3: Procedures

CS412/CS413. Introduction to Compilers Tim Teitelbaum. Lecture 21: Generating Pentium Code 10 March 08

Carnegie Mellon. 5 th Lecture, Jan. 31, Instructors: Todd C. Mowry & Anthony Rowe

Inline Assembler. Willi-Hans Steeb and Yorick Hardy. International School for Scientific Computing

Module 3 Instruction Set Architecture (ISA)

Computer Processors. Part 2. Components of a Processor. Execution Unit The ALU. Execution Unit. The Brains of the Box. Processors. Execution Unit (EU)

What is a Compiler? Compiler Construction SMD163. Why Translation is Needed: Know your Target: Lecture 8: Introduction to code generation

x86 64 Programming I CSE 351 Autumn 2018 Instructor: Justin Hsia

Computer Architecture and System Programming Laboratory. TA Session 3

Chapter 3: Addressing Modes

MACHINE-LEVEL PROGRAMMING I: BASICS

Function Call Convention

ADDRESSING MODES. Operands specify the data to be used by an instruction

Computer Architecture and Assembly Language. Practical Session 3

CMSC 313 COMPUTER ORGANIZATION & ASSEMBLY LANGUAGE PROGRAMMING PREVIEW SLIDES 16, SPRING 2013

Lecture 3: Instruction Set Architecture

Program Exploitation Intro

CPS104 Recitation: Assembly Programming

Machine Programming 1: Introduction

x86 Assembly Tutorial COS 318: Fall 2017

Machine-level Representation of Programs. Jin-Soo Kim Computer Systems Laboratory Sungkyunkwan University

Function Calls and Stack

Assembly Language Lab # 9

I/O Functions. Register Names and Purpose. Outline MIPS Assembly Language Programming. MIPS ALP, OISC and X86 ALP. SPIM: Hello World ALP 3/18/2015

Machine/Assembler Language Putting It All Together

Machine Level Programming I: Basics

Assembler Programming. Lecture 2

Introduction to Machine/Assembler Language

The von Neumann Machine

Transcription:

Introduction to 8086 Assembly Lecture 13 Inline Assembly

Inline Assembly Compiler-dependent GCC -> GAS (the GNU assembler)

Intel Syntax => AT&T Syntax Registers: eax => %eax Immediates: 123 => $123 Memory: lbl1 => $lbl1 (address of lbl1) [lbl1] => lbl1 (content of lbl1)

Intel Syntax => AT&T Syntax Operand order reversed: mov dest, src => mov src, dest Operand size in command (movb,movw,movl, addb,addw,addl, etc): mov eax, ebx => movl %ebx, %eax add dl, ch => addb %ch, %dl Indirect addressing mov eax, [ebx] => movl (%ebx), %eax add ax, [ebx+4] => addw 4(%ebx), %ax mov dword [ebx], 1 => movl $1, (%ebx)

Compile C to AT&T Assembly gcc -S myprogram.c gcc -S -masm=att myprogram.c

More on Intel vs. AT&T Syntax https://en.wikipedia.org/wiki/x86_assembly_language#syntax https://en.wikibooks.org/wiki/x86_assembly/gas_syntax https://imada.sdu.dk/courses/dm18/litteratur/intelnatt.htm

Basic inline assembly inline1.c inline2.c asm ("movl $1, %eax"); asm ("movl %eax, %ebx");

Basic inline assembly int a; inline3.c asm("movl $10, %eax; xchg %al, %ah"); asm("movl $10, %eax;" "xchg %al, %ah");

Global symbols (functions, global variables) inline4.c int g = 0; void print_sum(int a, int b) { printf("sum=%d\n",a+b); asm ("movl $110, g"); // NASM: mov dword [g], 110 printf("g=%d\n",g); asm ("pushl $10;" // NASM: push 10 "pushl $13;" // NASM: push 13 "call print_sum;" // NASM: call print_sum "addl $8, %esp;"); // NASM: add esp, 8

Global symbols (functions, global variables) inline4.c int g = 0; void print_sum(int a, int b) { printf("sum=%d\n",a+b); asm ("movl $110, g"); // NASM: mov dword [g], 110 printf("g=%d\n",g); asm ("pushl $10;" // NASM: push 10 "pushl $13;" // NASM: push 13 "call print_sum;" // NASM: call print_sum "addl $8, %esp;"); // NASM: add esp, 8

Global symbols (functions, global variables) inline4.c int g = 0; void print_sum(int a, int b) { printf("sum=%d\n",a+b); Do not use this technique! It might not alway work! asm ("movl $110, g"); // NASM: mov dword [g], 110 printf("g=%d\n",g); asm ("pushl $10;" // NASM: push 10 "pushl $13;" // NASM: push 13 "call print_sum;" // NASM: call print_sum "addl $8, %esp;"); // NASM: add esp, 8

Global symbols (functions, global variables) inline4.c int g = 0; void print_sum(int a, int b) { printf("sum=%d\n",a+b); what about local variables? asm ("movl $110, g"); // NASM: mov dword [g], 110 printf("g=%d\n",g); asm ("pushl $10;" // NASM: push 10 "pushl $13;" // NASM: push 13 "call print_sum;" // NASM: call print_sum "addl $8, %esp;"); // NASM: add esp, 8

How GCC handles inline assembly? inline5.c int a,b,c,d; scanf("%d %d", &a, &b); c = a+b; asm ("charand_command %ebx, %eax"); printf("a=%d b=%d, a+b=%d\n", a, b, c);

How GCC handles inline assembly? inline5.c int a,b,c,d; scanf("%d %d", &a, &b); c = a+b; asm ("charand_command %ebx, %eax"); printf("a=%d b=%d, a+b=%d\n", a, b, c); No Error Compiling to Assembly!

How GCC handles inline assembly? int a,b,c,d; inline5.c movl addl movl : -16(%rbp), %eax %edx, %eax %eax, -12(%rbp) inline5.asm scanf("%d %d", &a, &b); charand_command %ebx, %eax c = a+b; asm ("charand_command %ebx, %eax"); printf("a=%d b=%d, a+b=%d\n", a, b, c); movl movl movl movl movl movl -16(%rbp), %edx -20(%rbp), %eax -12(%rbp), %ecx %eax, %esi $.LC1, %edi $0, %eax :

How GCC handles inline assembly? int a,b,c,d; scanf("%d %d", &a, &b); inline5.c : movl -16(%rbp), %eax addl %edx, %eax movl %eax, -12(%rbp) charand_command %ebx, %eax inline5.asm c = a+b; asm ("charand_command %ebx, %eax"); printf("a=%d b=%d, a+b=%d\n", a, b, c); movl movl movl movl movl movl -16(%rbp), %edx -20(%rbp), %eax -12(%rbp), %ecx %eax, %esi $.LC1, %edi $0, %eax : just inserting inline assembly

How GCC handles inline assembly? int a,b,c,d; scanf("%d %d", &a, &b); inline5.c GCC just inserts inline assembly! c = a+b; asm ("charand_command %ebx, %eax"); printf("a=%d b=%d, a+b=%d\n", a, b, c); Assembler Error!

How GCC handles inline assembly? int a,b,c,d; scanf("%d %d", &a, &b); c = a+b; inline5.c GCC just inserts inline assembly! It has no idea what inline assembly is doing! asm ("charand_command %ebx, %eax"); printf("a=%d b=%d, a+b=%d\n", a, b, c); Assembler Error!

How GCC handles inline assembly? int a,b,c,d; scanf("%d %d", &a, &b); c = a+b; inline5.c asm ("charand_command %ebx, %eax"); printf("a=%d b=%d, a+b=%d\n", a, b, c); GCC just inserts inline assembly! It has no idea what inline assembly is doing! => side effects! Assembler Error!

What can go wrong? inline6.c int a,b,c; scanf("%d %d", &a, &b); c = a+b; asm ("movl $1, %eax;" "movl $1, %ebx;" "movl $1, %ecx;" "movl $1, %edx"); printf("a=%d b=%d, a+b=%d\n", a, b, c);

What can go wrong? inline6.c int a,b,c; scanf("%d %d", &a, &b); c = a+b; asm ("movl $1, %eax;" "movl $1, %ebx;" "movl $1, %ecx;" "movl $1, %edx"); printf("a=%d b=%d, a+b=%d\n", a, b, c);

What can go wrong? Case 1: inline7.c int a,b; register int c; scanf("%d %d", &a, &b); c = a+b; asm ("movl $1, %eax;" "movl $1, %ebx;" "movl $1, %ecx;" "movl $1, %edx"); printf("a=%d b=%d, a+b=%d\n", a, b, c);

What can go wrong? Case 1: inline7.c int a,b; register int c; scanf("%d %d", &a, &b); c = a+b; asm ("movl $1, %eax;" "movl $1, %ebx;" "movl $1, %ecx;" "movl $1, %edx"); printf("a=%d b=%d, a+b=%d\n", a, b, c); gcc tries to use a register to store c

What can go wrong? Case 1: inline7.c int a,b; register int c; scanf("%d %d", &a, &b); c = a+b; asm ("movl $1, %eax;" "movl $1, %ebx;" "movl $1, %ecx;" "movl $1, %edx"); printf("a=%d b=%d, a+b=%d\n", a, b, c);

What can go wrong? Case 1: inline7.c int a,b; register int c; scanf("%d %d", &a, &b); c = a+b; might or might not work as registers unexpectedly change. (worked in this case). asm ("movl $1, %eax;" "movl $1, %ebx;" "movl $1, %ecx;" "movl $1, %edx"); printf("a=%d b=%d, a+b=%d\n", a, b, c);

What can go wrong? Case 2: inline6.c int a,b,c; scanf("%d %d", &a, &b); c = a+b; asm ("movl $1, %eax;" "movl $1, %ebx;" "movl $1, %ecx;" "movl $1, %edx"); b.nasihatkon@kntu:lecture13$ gcc -m32 inline6.c &&./a.out 2 3 a=2 b=3, a+b=5 b.nasihatkon@kntu:lecture13$ gcc -m32 -O1 inline6.c &&./a.out 2 3 a=1 b=1, a+b=2 printf("a=%d b=%d, a+b=%d\n", a, b, c); turn on optimization

Solution 1: use volatile keyword inline8.c volatile int a,b,c; scanf("%d %d", &a, &b); c = a+b; asm ("movl $1, %eax;" "movl $1, %ebx;" "movl $1, %ecx;" "movl $1, %edx"); b.nasihatkon@kntu:lecture13$ gcc -m32 inline8.c &&./a.out 2 3 a=2 b=3, a+b=5 b.nasihatkon@kntu:lecture13$ gcc -m32 -O1 inline8.c &&./a.out 2 3 a=2 b=3, a+b=5 printf("a=%d b=%d, a+b=%d\n", a, b, c); turn on optimization

Solution 1: use volatile keyword inline8.c volatile int a,b,c; renders optimization useless! scanf("%d %d", &a, &b); c = a+b; asm ("movl $1, %eax;" "movl $1, %ebx;" "movl $1, %ecx;" "movl $1, %edx"); b.nasihatkon@kntu:lecture13$ gcc -m32 inline8.c &&./a.out 2 3 a=2 b=3, a+b=5 b.nasihatkon@kntu:lecture13$ gcc -m32 -O1 inline8.c &&./a.out 2 3 a=2 b=3, a+b=5 printf("a=%d b=%d, a+b=%d\n", a, b, c); turn on optimization

Learn more about volatile keyword https://barrgroup.com/embedded-systems/how-to/c-volatile-keyword https://www.geeksforgeeks.org/understanding-volatile-qualifier-in-c/ https://en.wikipedia.org/wiki/volatile_(computer_programming)

Solution 2: tell compiler what registers are affected inline8.c volatile int a,b,c; scanf("%d %d", &a, &b); c = a+b; asm ("movl $1, %eax;" "movl $1, %ebx;" "movl $1, %ecx;" "movl $1, %edx"); printf("a=%d b=%d, a+b=%d\n", a, b, c);

Extended Inline Assembly asm ( assembly code : output registers : input registers : clobbered registers);

Solution 2: tell compiler what registers are affected inline9.c int a,b,c; scanf("%d %d", &a, &b); c = a+b; asm ("movl $1, %%eax;" "movl $1, %%ebx;" "movl $1, %%ecx;" "movl $1, %%edx;" : : : "eax", "ebx", "ecx", "edx"); printf("a=%d b=%d, a+b=%d\n", a, b, c);

Solution 2: tell compiler what registers are affected inline9.c int a,b,c; scanf("%d %d", &a, &b); c = a+b; asm ("movl $1, %%eax;" "movl $1, %%ebx;" "movl $1, %%ecx;" "movl $1, %%edx;" : : : "eax", "ebx", "ecx", "edx"); printf("a=%d b=%d, a+b=%d\n", a, b, c); use double % for registers

Solution 2: tell compiler what registers are affected inline9.c int a,b,c; scanf("%d %d", &a, &b); c = a+b; asm ("movl $1, %%eax;" "movl $1, %%ebx;" clobbered registers "movl $1, %%ecx;" "movl $1, %%edx;" : : : "eax", "ebx", "ecx", "edx"); printf("a=%d b=%d, a+b=%d\n", a, b, c);

Solution 2: tell compiler what registers are affected inline9.c int a,b,c; b.nasihatkon@kntu:lecture13$ gcc -m32 inline9.c &&./a.out scanf("%d %d", &a, &b); 2 3 a=2 b=3, a+b=5 c = a+b; b.nasihatkon@kntu:lecture13$ gcc -m32 -O1 inline9.c &&./a.out 2 3 a=2 b=3, a+b=5 asm ("movl $1, %%eax;" "movl $1, %%ebx;" "movl $1, %%ecx;" turn on optimization "movl $1, %%edx;" : : : "eax", "ebx", "ecx", "edx"); printf("a=%d b=%d, a+b=%d\n", a, b, c);

Solution 2: tell compiler what registers are affected inline10.c int a,b; register int c; scanf("%d %d", &a, &b); c = a+b; asm ("movl $1, %%eax;" "movl $1, %%ebx;" "movl $1, %%ecx;" "movl $1, %%edx;" : : : "eax", "ebx", "ecx", "edx"); printf("a=%d b=%d, a+b=%d\n", a, b, c);

Solution 2: tell compiler what registers are affected inline10.c int a,b; register int c; scanf("%d %d", &a, &b); c = a+b; asm ("movl $1, %%eax;" "movl $1, %%ebx;" "movl $1, %%ecx;" "movl $1, %%edx;" : : : "eax", "ebx", "ecx", "edx"); printf("a=%d b=%d, a+b=%d\n", a, b, c);

Give input to inline assembly #include <string.h> char msg[] = "Salaaaam Kako!\n"; int length = strlen(msg); inline11.c # sys_write movl $4, %eax # syscall no. movl $1, %ebx # file handle movl $msg, %ecx # message movl $13, %edx # length int $0x80 asm ("movl $4, %%eax;" // system call 4: sys_write "movl $1, %%ebx;" // file handle 1: stdout "int $0x80;" // syscall : : "c" (msg), "d" (length) : "eax", "ebx"); no outputs inputs (input constraints) clobbered registers

Give input to inline assembly #include <string.h> char msg[] = "Salaaaam Kako!\n"; int length = strlen(msg); inline11.c # sys_write movl $4, %eax # syscall no. movl $1, %ebx # file handle movl $msg, %ecx # message movl $13, %edx # length int $0x80 asm ("movl $4, %%eax;" // system call 4: sys_write "movl $1, %%ebx;" // file handle 1: stdout "int $0x80;" // syscall : : "c" (msg), "d" (length) : "eax", "ebx"); ecx edx

Give input to inline assembly #include <string.h> char msg[] = "Salaaaam Kako!\n"; int length = strlen(msg); inline11.c # sys_write movl $4, %eax # syscall no. movl $1, %ebx # file handle movl $msg, %ecx # message movl $13, %edx # length int $0x80 asm ("movl $4, %%eax;" // system call 4: sys_write "movl $1, %%ebx;" // file handle 1: stdout "int $0x80;" // syscall : : "c" (msg), "d" (length) : "eax", "ebx");

Registers a b c d S D r f eax, ax, al ebx, bx, bl ecx, cx, cl edx, dx, dl esi, si edi, di register a floating point register

Get output inline12.c int x = 12, y=13; printf("x=%d, y=%d\n", x,y); asm ("xchgl %%eax, %%ebx" : "=a" (x), "=b" (y) : "a" (x), "b" (y) : ); printf("x=%d, y=%d\n", x,y);

Get output inline12.c int x = 12, y=13; printf("x=%d, y=%d\n", x,y); asm ("xchgl %%eax, %%ebx" : "=a" (x), "=b" (y) : "a" (x), "b" (y) : ); outputs inputs printf("x=%d, y=%d\n", x,y);

Get output inline12.c int x = 12, y=13; printf("x=%d, y=%d\n", x,y); asm ("xchgl %%eax, %%ebx" : "=a" (x), "=b" (y) : "a" (x), "b" (y) : ); outputs inputs printf("x=%d, y=%d\n", x,y);

Get output inline13.c int x = 12, y=13; printf("x=%d, y=%d\n", x,y); asm ("xchgl %0, %1" : "=r" (x), "=r" (y) : "0" (x), "1" (y) : ); outputs inputs printf("x=%d, y=%d\n", x,y);

Get output inline13.c int x = 12, y=13; printf("x=%d, y=%d\n", x,y); asm ("xchgl %0, %1" : "=r" (x), "=r" (y) : "0" (x), "1" (y) : ); outputs inputs printf("x=%d, y=%d\n", x,y);

Use Intel Syntax with GCC Modern versions of GAS support Intel Syntax The GAS GNU Syntax is a bit different from NASM Syntax the.intel_syntax and.att_syntax directives

Use Intel Syntax with GCC Put your code between the.intel_syntax (or.intel_syntax noprefix) and.att_syntax directives Better solution: Compile with -masm=intel gcc option.

Use Intel Syntax with GCC #include <string.h> inline14.c char msg[] = "Salaaaam Kako!\n"; int length = strlen(msg); asm ("mov eax, 4;" // system call 4: sys_write "mov ebx, 1;" // file handle 1: stdout "int 0x80;" // syscall : : "c" (msg), "d" (length) : "eax", "ebx");

Use Intel Syntax with GCC #include <string.h> inline14.c char msg[] = "Salaaaam Kako!\n"; int length = strlen(msg); asm ("mov eax, 4;" // system call 4: sys_write "mov ebx, 1;" // file handle 1: stdout "int 0x80;" // syscall : : "c" (msg), "d" (length) : "eax", "ebx");

Be careful with compiler optimization! inline15.c int count = 0; asm ("mov eax, 0" : : : "eax"); for (int i = 0; i < 10; i++) { asm ("inc eax;" : "=a" (count) : : ); printf("count=%d\n", count);

Be careful with compiler optimization! inline15.c int count = 0; asm ("mov eax, 0" : : : "eax"); for (int i = 0; i < 10; i++) { asm ("inc eax;" : "=a" (count) : : ); printf("count=%d\n", count);

volatile keyword for inline assembly inline16.c int count = 0; asm volatile ("mov eax, 0" : : : "eax"); for (int i = 0; i < 10; i++) { asm volatile ("inc eax;" : "=a" (count) : : ); printf("count=%d\n", count);

volatile keyword for inline assembly inline16.c int count = 0; asm volatile ("mov eax, 0" : : : "eax"); for (int i = 0; i < 10; i++) { asm volatile ("inc eax;" : "=a" (count) : : ); printf("count=%d\n", count);

Inline assembly is compiler-dependent Microsoft Visual C https://msdn.microsoft.com/en-us/library/45yd4tzz.aspx

References & further reading https://gcc.gnu.org/onlinedocs/gcc/constraints.html https://www.codeproject.com/articles/15971/using-inline-assembly-in-c-c https://www.ibiblio.org/gferg/ldp/gcc-inline-assembly-howto.html https://www.cs.virginia.edu/~clc5q/gcc-inline-asm.pdf