From f28ef1e151de187197b1635cce071a5352d62612 Mon Sep 17 00:00:00 2001 From: Price Hiller Date: Thu, 5 Dec 2024 22:37:44 -0600 Subject: [PATCH] cs-3843: add assignment 12 --- .../CS-3843/Assignments/12/Assignment.typ | 1178 +++++++++++++++++ 1 file changed, 1178 insertions(+) create mode 100644 Fall-2024/CS-3843/Assignments/12/Assignment.typ diff --git a/Fall-2024/CS-3843/Assignments/12/Assignment.typ b/Fall-2024/CS-3843/Assignments/12/Assignment.typ new file mode 100644 index 0000000..04d09f2 --- /dev/null +++ b/Fall-2024/CS-3843/Assignments/12/Assignment.typ @@ -0,0 +1,1178 @@ +#import "@preview/codly:1.1.1": * +#import "@preview/codly-languages:0.1.1": * +#show: codly-init.with() + +#codly( + stroke: .5pt + luma(120), + display-name: false, + number-format: none, + zebra-fill: orange.lighten(75%), + fill: orange.lighten(90%), +) + +#show link: set text(blue) +#set text(font: "Calibri") +#show raw: set text(font: "Fira Code") +#set table.header(repeat: false) +#set table(stroke: (x, y) => ( + left: if x > 0 { + .1pt + }, + top: if y == 1 { + 0.5pt + } else if y > 1 { + 0.1pt + }, +)) + +#set page(margin: (y: .25in, x: .25in)) +#let solve(solution) = { + block( + outset: 3pt, + inset: 3pt, + stroke: blue + .3pt, + fill: rgb(0, 149, 255, 15%), + radius: 4pt, + )[#solution] +} + +#let solvein(solution) = { + let outset = 3pt + h(outset) + box( + outset: outset, + stroke: blue + .3pt, + fill: rgb(0, 149, 255, 15%), + radius: 4pt, + )[#solution] +} + +#let note(content) = { + block( + outset: 3pt, + inset: 5pt, + stroke: luma(20%) + .3pt, + fill: luma(95%), + radius: 4pt, + )[#content] +} + +#let notein(content) = { + let outset = 3pt + h(outset) + box( + outset: outset, + stroke: luma(20%) + .3pt, + fill: luma(95%), + radius: 4pt, + )[#content] +} + +#align(center)[ + = CS 3843 Computer Organization + HW 12\ + #underline[Price Hiller] *|* #underline[zfp106] +] +#line(length: 100%, stroke: .25pt) + +#note[ + As a note I'm skipping the "cruft" inside the assembly output for this homework (stuff like the `.text`, `.file` directive, and whatnot). That's vaguely external to our actual code for use in the assembler, not a direct one-to-one translation of our code. I am focusing on the important bits. + + On some stuff, I may ignore some of the C code as the assembly generated doesn't cleanly match up at all. I've done my absolute best to keep things coherent, but I do want to apologize in advance if this proves hard to follow. +] + +1. Please see below for the C version. You need to generate the assembly version of this C version. + In your submission document, you need to include the screenshot of the assembly version. Then + you need to write a discussion on the assembly version. Make sure to include what’s happening + at each line of your assembly code, also you need to include how the control has been + transferred from one place to another of your program + + #solve[ + #table( + columns: 3, + table.header([C code], [Assembly Code], [Description]), + [ + ```c + long absdiff_se(long x, long y) { + ``` + ], + [ + ```asm + absdiff_se: + ``` + ], + [ + Create a label named ```asm absdiff_se```, the name of our C function. + ], + + [ + ```c + if (x < y) { + ``` + ], + [ + ```asm + cmpq %rsi, %rdi + jge .L2 + ``` + ], + [ + Compare the two inputs of the function to each other and jump to the label `.L2` if ```c x >= y``` (by checking if the `SF` and `OF` flags are the same as a result of the ```asm cmpq``` instruction.) + ], + + [ + ```c + lt_cnt++; + ``` + ], + [ + ```asm + movq lt_cnt@GOTPCREL(%rip), %rdx + movq (%rdx), %rax + addq $1, %rax + ``` + ], + [ + 1. Load the value for ```c lt_cnt``` from the global offset table into ```asm %rdx```. + 2. Load that derefenced value from ```asm %rdx``` into ```asm %rax``` + 3. Finally, increment ```asm %rax``` by `1`, equivalent to ```c lt_cnt++``` + ], + + [ + ```c + result = y - x; + ``` + ], + [ + ```asm + movq %rax, (%rdx) + movq %rsi, %rax + subq %rdi, %rax + ret + ``` + ], + [ + 1. Copy the value of ```asm %rax``` into the value pointed to by ```asm (%rdx)``` + 2. Copy the value of ```asm %rsi``` into ```asm %rax``` + 3. Finally, subtract ```asm %rdi``` from ```asm %rax```, storing the result in ```asm %rax``` + 4. Return control to the caller + ], + + [ + ```c + } else { + ``` + ], + [ + ```asm + .L2: + ``` + ], + [ + If the earlier ```asm jge .L2``` found that the flags `SF` and `OF` were the same, we'll jump to this label/ + ], + + [ + ```c + ge_cnt++; + ``` + ], + [ + ```asm + movq ge_cnt@GOTPCREL(%rip), %rdx + movq (%rdx), %rax + addq $1, %rax + ``` + ], + [ + 1. Load the value for ```c ge_cnt``` from the global offset table into ```asm %rdx```. + 2. Load that derefenced value from ```asm %rdx``` into ```asm %rax``` + 3. Finally, increment ```asm %rax``` by `1`, equivalent to ```c gt_cnt++``` + ], + + [ + ```c + result = x - y; + ``` + ], + [ + ```asm + movq %rax, (%rdx) + movq %rdi, %rax + subq %rsi, %rax + ret + ``` + ], + [ + 1. Copy the value of ```asm %rax``` into the value pointed to by ```asm (%rdx)``` + 2. Copy the value of ```asm %rdi``` into ```asm %rax``` + 3. Finally, subtract ```asm %rsi``` from ```asm %rax```, storing the result in ```asm %rax``` + 4. Return control to the caller + ], + ) + #note[ + You may have noticed I skipped over the ```c return result;``` chunk of the C code. This is because that chunk is satisfied by the early `ret` calls in both branches of the assembly. Secondly, I skipped the `xorl` instructions as they're merely clearing the registers. + ] + ] + #note[ + #table( + columns: 2, + table.header( + [Original C Code], + [Produced Assembly via ```sh gcc -Og -S```], + ), + + [ + ```c + long lt_cnt = 0; + long ge_cnt = 0; + long absdiff_se(long x, long y) { + long result; + if (x < y) { + lt_cnt++; + result = y - x; + } else { + ge_cnt++; + result = x - y; + } + return result; + } + ``` + ], + [ + ```asm + .file "t.c" + .text + .globl absdiff_se + .type absdiff_se, @function + absdiff_se: + .LFB0: + .cfi_startproc + cmpq %rsi, %rdi + jge .L2 + movq lt_cnt@GOTPCREL(%rip), %rdx + movq (%rdx), %rax + addq $1, %rax + movq %rax, (%rdx) + movq %rsi, %rax + subq %rdi, %rax + xorl %edx, %edx + xorl %esi, %esi + xorl %edi, %edi + ret + .L2: + movq ge_cnt@GOTPCREL(%rip), %rdx + movq (%rdx), %rax + addq $1, %rax + movq %rax, (%rdx) + movq %rdi, %rax + subq %rsi, %rax + xorl %edx, %edx + xorl %esi, %esi + xorl %edi, %edi + ret + .cfi_endproc + .LFE0: + .size absdiff_se, .-absdiff_se + .globl ge_cnt + .bss + .align 8 + .type ge_cnt, @object + .size ge_cnt, 8 + ge_cnt: + .zero 8 + .globl lt_cnt + .align 8 + .type lt_cnt, @object + .size lt_cnt, 8 + lt_cnt: + .zero 8 + .ident "GCC: (GNU) 13.3.0" + .section .note.GNU-stack,"",@progbits + ``` + ], + ) + ] + +2. Please see below for the C version. You need to generate the assembly version of this C version. + In your submission document, you need to include the screenshot of the assembly version. Then + you need to write a discussion on the assembly version. Make sure to include what’s happening + at each line of your assembly code, also you need to include how the control has been + transferred from one place to another of your program. + #solve[ + #table( + columns: 3, + table.header([C code], [Assembly Code], [Description]), + [ + ```c + long absdiff(long x, long y) { + ``` + ], + [ + ```asm + absdiff: + ``` + ], + [ + Create a label named ```asm absdiff```, the name of our C function. + ], + + [ + ```c + if (x < y) { + ``` + ], + [ + ```asm + cmpq %rsi, %rdi + jge .L2 + ``` + ], + [ + Compare the two inputs of the function to each other and jump to the label `.L2` if ```c x >= y``` (by checking if the `SF` and `OF` flags are the same as a result of the ```asm cmpq``` instruction.) + ], + + [ + ```c + result = y - x; + ``` + ], + [ + ```asm + movq %rsi, %rax + subq %rsi, %rax + ret + ``` + ], + [ + + Copy the value of ```asm %rsi``` into ```asm %rax``` + + Finally, subtract ```asm %rdi``` from ```asm %rax```, storing the result in ```asm %rax``` + + Return control to the caller + ], + + [ + ```c + else + ``` + ], + [ + ```asm + .L2: + ``` + ], + [ + If the earlier ```asm jge .L2``` found that the flags `SF` and `OF` were the same, we'll jump to this label/ + ], + + [ + ```c + result = x - y; + ``` + ], + [ + ```asm + movq %rdi, %rax + subq %rsi, %rax + ret + ``` + ], + [ + 1. Copy the value of ```asm %rax``` into the value pointed to by ```asm (%rdx)``` + 2. Copy the value of ```asm %rdi``` into ```asm %rax``` + 3. Finally, subtract ```asm %rsi``` from ```asm %rax```, storing the result in ```asm %rax``` + 4. Return control to the caller + ], + ) + ] + + #note[ + #table( + columns: 2, + table.header( + [Original C Code], + [Produced Assembly via ```sh gcc -Og -S```], + ), + + [ + ```c + long absdiff(long x, long y) { + long result; + if (x < y) + result = y - x; + else + result = x - y; + return result; + } + ``` + ], + [ + ```asm + .file "t.c" + .text + .globl absdiff + .type absdiff, @function + absdiff: + .LFB0: + .cfi_startproc + cmpq %rsi, %rdi + jge .L2 + movq %rsi, %rax + subq %rdi, %rax + xorl %esi, %esi + xorl %edi, %edi + ret + .L2: + movq %rdi, %rax + subq %rsi, %rax + xorl %esi, %esi + xorl %edi, %edi + ret + .cfi_endproc + .LFE0: + .size absdiff, .-absdiff + .ident "GCC: (GNU) 13.3.0" + .section .note.GNU-stack,"",@progbits + ``` + ], + ) + ] + + +3. Please see below for the C version. You need to generate the assembly version of this C version. + In your submission document, you need to include the screenshot of the assembly version. Then + you need to write a discussion on the assembly version. Make sure to include what’s happening + at each line of your assembly code, also you need to include how the control has been + transferred from one place to another of your program. + #solve[ + #table( + columns: 3, + table.header([C code], [Assembly Code], [Description]), + [ + ```c + long fact_do(long n) { + ``` + ], + [ + ```asm + fact_do: + ``` + ], + [ + Create a label named ```asm fact_do```, the name of our C function. + ], + + [ + ```c + long result = 1; + ``` + ], + [ + ```asm + movl $1, %eax + ``` + ], + [ + Assign ```c result``` to `1`, in assembly this means putting ```asm $1``` in the ```asm %eax``` register (the return register) as we will be returning this value after the function operation. + ], + + [ + ```c + do { + ``` + ], + [ + ```asm + .L2: + ``` + ], + [ + Create a label named ```asm .L2:``` for control operations on the `do-while` loop. + ], + + [ + ```c + result *=n; + ``` + ], + [ + ```asm + imulq %rdi, %rax + ``` + ], + [ + Multiply the input value by ```asm %rax``` and store the result of the multiplication in ```asm %rax```. + ], + + [ + ```c + n = n - 1; + ``` + ], + [ + ```asm + subq $1, %rdi + ``` + ], + [ + Subtract `1` from our input value and store the result back in the input value's register, that being ```asm %rdi```. + ], + + [ + ```c + } while (n > 1); + ``` + ], + [ + ```asm + cmpq $1, %rdi + jg .L2 + ``` + ], + [ + 1. Run a comparison between the value ```asm $1``` and ```asm %rdi``` to set flags. + 2. If `~(SF^OF) & ~ZF`, then jump to the label ```asm .L2```. (Basically if the value stored in ```asm %rdi``` is more than `1`, jump to ```asm .L2```) + ], + + [ + ```c + return result; + ``` + ], + [ + ```asm + ret + ``` + ], + [ + _Technically_ this isn't one to one. By setting our return value as `result` we've informed the compiler to insert values into ```asm %rax``` as that is our return register. + ], + ) + ] + #note[ + #table( + columns: 2, + table.header( + [Original C Code], + [Produced Assembly via ```sh gcc -Og -S```], + ), + + [ + ```c + long fact_do(long n) { + long result = 1; + do { + result *= n; + n = n - 1; + } while (n > 1); + return result; + } + ``` + ], + [ + ```asm + .file "t.c" + .text + .globl fact_do + .type fact_do, @function + fact_do: + .LFB0: + .cfi_startproc + movl $1, %eax + .L2: + imulq %rdi, %rax + subq $1, %rdi + cmpq $1, %rdi + jg .L2 + xorl %edi, %edi + ret + .cfi_endproc + .LFE0: + .size fact_do, .-fact_do + .ident "GCC: (GNU) 13.3.0" + .section .note.GNU-stack,"",@progbits + ``` + ], + ) + ] + +4. Please see below for the C version. You need to generate the assembly version of this C version. + In your submission document, you need to include the screenshot of the assembly version. Then + you need to write a discussion on the assembly version. Make sure to include what’s happening + at each line of your assembly code, also you need to include how the control has been + transferred from one place to another of your program. + #solve[ + #table( + columns: 3, + table.header([C code], [Assembly Code], [Description]), + [ + ```c + long fact_while(long n) { + ``` + ], + [ + ```asm + fact_while: + ``` + ], + [ + Create a label named ```asm fact_while```, the name of our C function. + ], + + [ + ```c + long result = 1; + ``` + ], + [ + ```asm + movl $1, %eax + ``` + ], + [ + Assign ```c result``` to `1`, in assembly this means putting ```asm $1``` in the ```asm %eax``` register (the return register) as we will be returning this value after the function operation. + ], + + [ + ```c + while (/* omitted */) + ``` + ], + [ + ```asm + .L3: + ... ; omitted + .L2: + ... ; omitted + ``` + ], + [ + 1. Create a label named ```asm .L3:``` for control operations on the `while` loop. This will allow access to the inner body of the loop. + 2. Create a separate label to handle the comparison (`n > 1`), named ```asm .L2:```, this will be jumped to unconditionally so the comparison can be validated + ], + + [ + ```c + (n > 1) + ``` + ], + [ + ```asm + cmpq $1, %rdi + jg .L3 + ``` + ], + [ + 1. Run a comparison between the value ```asm $1``` and ```asm %rdi``` to set flags. + 2. If `~(SF^OF) & ~ZF`, then jump to the label ```asm .L3```. (Basically if the value stored in ```asm %rdi``` is more than `1`, jump to ```asm .L3```) + ], + + [ + ```c + result *=n; + ``` + ], + [ + ```asm + imulq %rdi, %rax + ``` + ], + [ + Multiply the input value by ```asm %rax``` and store the result of the multiplication in ```asm %rax```. + ], + + [ + ```c + n = n - 1; + ``` + ], + [ + ```asm + subq $1, %rdi + ``` + ], + [ + Subtract `1` from our input value and store the result back in the input value's register, that being ```asm %rdi```. + ], + + [ + ```c + return result; + ``` + ], + [ + ```asm + ret + ``` + ], + [ + _Technically_ this isn't one to one. By setting our return value as `result` we've informed the compiler to insert values into ```asm %rax``` as that is our return register. + ], + ) + ] + #note[ + #table( + columns: 2, + table.header( + [Original C Code], + [Produced Assembly via ```sh gcc -Og -S```], + ), + + [ + ```c + long fact_while(long n) { + long result = 1; + while (n > 1) { + result *= n; + n = n - 1; + } + return result; + } + ``` + ], + [ + ```asm + .file "t.c" + .text + .globl fact_while + .type fact_while, @function + fact_while: + .LFB0: + .cfi_startproc + movl $1, %eax + jmp .L2 + .L3: + imulq %rdi, %rax + subq $1, %rdi + .L2: + cmpq $1, %rdi + jg .L3 + xorl %edi, %edi + ret + .cfi_endproc + .LFE0: + .size fact_while, .-fact_while + .ident "GCC: (GNU) 13.3.0" + .section .note.GNU-stack,"",@progbits + ``` + ], + ) + ] + +5. Please see below for the C version. You need to generate the assembly version of this C version. + In your submission document, you need to include the screenshot of the assembly version. Then + you need to write a discussion on the assembly version. Make sure to include what’s happening + at each line of your assembly code, also you need to include how the control has been + transferred from one place to another of your program. + #note[ + Due to a lack of decent annotation tools on code in the core of Typst, the below description is kinda messy to follow. I do apologize for that, but I've done my best to ensure it's understandable. + ] + #solve[ + #table( + columns: 3, + table.header([C code], [Assembly Code], [Description]), + [ + ```c + long fact_for(long n) { + ``` + ], + [ + ```asm + fact_for: + ``` + ], + [ + Create a label named ```asm fact_for```, the name of our C function. + ], + + [ + ```c + long result = 1; + ``` + ], + [ + ```asm + movl $1, %edx + ``` + ], + [ + Assign ```c result``` to `1`, in assembly this means putting ```asm $1``` in the ```asm %edx``` register. + ], + + [ + ```c + for (i = 2; i <= n; i++) + ``` + ], + [ + ```asm + jmp .L2 + .L3: + ... ; omitted + addq $1, %rax + .L2: + cmpq %rdi, %rax + jle .L3 + ... ; omitted + ``` + ], + [ + + Create a label named ```asm .L3:``` for control operations on the `for` loop. This will allow access to the inner body of the loop. + + Create a separate label to handle the comparison (`i <= 1`), named ```asm .L2:```, this will be jumped to unconditionally so the comparison can be validated + + Run a comparison between the value ```asm $1``` and ```asm %rdi``` to set flags. (The `cmpq` instruction). + + If `(SF^OF) | ZF`, then jump to the label ```asm .L3```. Basically if the value stored in ```asm %rdi``` is less than `2`, jump to ```asm .L3```. (The `jle .L3` instruction). + + If we jump to the label `.L3`, we increment `%rax` (which stored `i`) by one, after executing the rest of the for loop body (see the next section). + ], + + [ + ```c + result *=n; + ``` + ], + [ + ```asm + imulq %rax, %rdx + ``` + ], + [ + Multiply the input value by ```asm %rax``` and store the result of the multiplication in ```asm %rdx```. + ], + + [ + ```c + return result; + ``` + ], + [ + ```asm + movq %rdx, %rax + ret + ``` + ], + [ + Ensure where we've stored the result of our operations (in this case ```asm %rdx```) is put into a valid return register for use by the caller by copying ```asm %rdx``` to ```asm %rax```. + ], + ) + ] + #note[ + #table( + columns: 2, + table.header( + [Original C Code], + [Produced Assembly via ```sh gcc -Og -S```], + ), + + [ + ```c + long fact_for(long n) { + long i; + long result = 1; + for (i = 2; i <= n; i++) + result *= i; + return result; + } + ``` + ], + [ + ```asm + .file "t.c" + .text + .globl fact_for + .type fact_for, @function + fact_for: + .LFB0: + .cfi_startproc + movl $1, %edx + movl $2, %eax + jmp .L2 + .L3: + imulq %rax, %rdx + addq $1, %rax + .L2: + cmpq %rdi, %rax + jle .L3 + movq %rdx, %rax + xorl %edx, %edx + xorl %edi, %edi + ret + .cfi_endproc + .LFE0: + .size fact_for, .-fact_for + .ident "GCC: (GNU) 13.3.0" + .section .note.GNU-stack,"",@progbits + ``` + ], + ) + ] + +6. Please see below for the C version. You need to generate the assembly version of this C version. + In your submission document, you need to include the screenshot of the assembly version. Then + you need to write a discussion on the assembly version. Make sure to include what’s happening + at each line of your assembly code, also you need to include how the control has been + transferred from one place to another of your program. + #note[ + This is where it has gotten hilariously messy to even _try_ to track the matching C code for the given assembly output. As such, I've chosen to _not_ bother lining up C code and am instead going to go line by line on the assembly as I feel that may be a tiny bit easier to follow. + ] + #solve[ + #table( + columns: 2, + table.header([Assembly Code], [Description]), + [ + ```asm + switch_eg: + ``` + ], + [ + Define a label named ```asm switch_eg```. + ], + + [ + ```asm + subq $100, %rsi + ``` + ], + [ + Substract `100` from ```asm %rsi```, storing the result into ```asm %rsi```. + ], + + [ + ```asm + cmpq $6, %rsi + ``` + ], + [ + Compare the value `6` with the current value of ```asm %rsi```, setting the appropriate flags based on the comparison. + ], + + [ + ```asm + ja .L8 + ``` + ], + [ + Jump to the label `.L8`, if the flags satisfy `~CF & ~ZF`. + ], + + [ + ```asm + leaq .L4(%rip), %rcx + ``` + ], + [ + Load the effective address from the global offset table into ```asm %rcx``` + ], + + [ + ```asm + movslq (%rcx,%rsi,4), %rax + ``` + ], + [ + Copy the value at `%rcx + 4 * %rsi` into ```asm %rax```, used to calculate offset for our switch statements. + ], + + [ + ```asm + addq %rcx, %rax + ``` + ], + [ + Add the value stored in ```asm %rcx``` into ```asm %rax``` + ], + + [ + ```asm + jmp *%rax + ``` + ], + [ + Do a indirect jump to load the address stored at ```asm %rax``` for our switch statements. + _Begin to cry._ + ], + + [ + ```asm + .L4: + .long .L7-.L4 + .long .L8-.L4 + .long .L6-.L4 + .long .L5-.L4 + .long .L3-.L4 + .long .L8-.L4 + .long .L3-.L4 + .text + ``` + ], + [ + Big ol' jump table. + + ], + + [ + ```asm + .L7: + leaq (%rdi,%rdi,2), %rax + leaq (%rdi,%rax,4), %rdi + jmp .L2 + ``` + ], + [ + Loads data based on ```asm %rdi``` and ```asm %rax``` into ```asm %rax``` and ```asm %rdi``` respectively based on offsets. _Cry even more_. + + + Then jump to the label ```asm .L2``` + ], + + [ + ```asm + .L6: + addq $10, %rdi + ``` + ], + [ + Add `10` to ```asm %rdi```, this corresponds to our case `102`. + ], + + [ + ```asm + .L5: + addq $11, %rdi + ``` + ], + [ + Add `11` to ```asm %rdi```, this corresponds to our case `103`. + ], + + [ + ```asm + .L2: + movq %rdi, (%rdx) + ... ; omitted + ret + ``` + ], + [ + Finally load our calculated value into the ```c *dest``` location via derefence. _Cry until we can't see._ + + Finally, _finally_, return control back to the caller. + ], + + [ + ```asm + .L3: + imulq %rdi, %rdi + jmp .L2 + ``` + ], + [ + This corresponds to cases `104` — `106`. + + Multiply ```asm %rdi``` by itself, storing the result back in itself (```asm %rdi```). + + Jump to the label ```asm .L2```. + ], + + [ + ```asm + .L8: + movl $0, %edi + jmp .L2 + ``` + ], + [ + This corresponds to the default case. + + Copy the value `0` into ```asm %edi``` and jump to the label ```asm .L2```. + ], + ) + ] + #note[Wow! That sucked.] + #note[ + #table( + columns: 2, + table.header( + [Original C Code], + [Produced Assembly via ```sh gcc -Og -S```], + ), + + [ + ```c + void switch_eg(long x, long n, long *dest) { + long val = x; + switch (n) { + case 100: + val *= 13; + break; + case 102: + val += 10; + /* Fall through */ + case 103: + val += 11; + break; + case 104: + case 106: + val *= val; + break; + default: + val = 0; + } + *dest = val; + } + ``` + ], + [ + ```asm + .file "t.c" + .text + .globl switch_eg + .type switch_eg, @function + switch_eg: + .LFB0: + .cfi_startproc + subq $100, %rsi + cmpq $6, %rsi + ja .L8 + leaq .L4(%rip), %rcx + movslq (%rcx,%rsi,4), %rax + addq %rcx, %rax + jmp *%rax + .section .rodata + .align 4 + .align 4 + .L4: + .long .L7-.L4 + .long .L8-.L4 + .long .L6-.L4 + .long .L5-.L4 + .long .L3-.L4 + .long .L8-.L4 + .long .L3-.L4 + .text + .L7: + leaq (%rdi,%rdi,2), %rax + leaq (%rdi,%rax,4), %rdi + jmp .L2 + .L6: + addq $10, %rdi + .L5: + addq $11, %rdi + .L2: + movq %rdi, (%rdx) + xorl %eax, %eax + xorl %edx, %edx + xorl %ecx, %ecx + xorl %esi, %esi + xorl %edi, %edi + ret + .L3: + imulq %rdi, %rdi + jmp .L2 + .L8: + movl $0, %edi + jmp .L2 + .cfi_endproc + .LFE0: + .size switch_eg, .-switch_eg + .ident "GCC: (GNU) 13.3.0" + .section .note.GNU-stack,"",@progbits + ``` + ], + ) + ]