# Comparing arrays of numbers. == code array-equal?: # a : (addr array int), b : (addr array int) -> eax : boolean # pseudocode: # lena = a->length # if (lena != b->length) return false # i = 0 # curra = a->data # currb = b->data # while i < lena # i1 = *curra # i2 = *currb # if (c1 != c2) return false # i+=4, curra+=4, currb+=4 # return true # # registers: # i: ecx # lena: edx # curra: esi # currb: edi # i1: eax # i2: ebx # # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp # . save registers 51/push-ecx 52/push-edx 53/push-ebx 56/push-esi 57/push-edi # esi = a 8b/-> *(ebp+8) 6/r32/esi # edi = b 8b/-> *(ebp+0xc) 7/r32/edi # var lena/edx : int = a->length 8b/-> *esi 2/r32/edx $array-equal?:lengths: # if (lena != b->length) return false 39/compare *edi 2/r32/edx 75/jump-if-not-equal $array-equal?:false/disp8 # var curra/esi : (addr byte) = a->data 81 0/subop/add %esi 4/imm32 # var currb/edi : (addr byte) = b->data 81 0/subop/add %edi 4/imm32 # var i/ecx : int = 0 31/xor %ecx 1/r32/ecx # var vala/eax : int # var valb/ebx : int $array-equal?:loop: # if (i >= lena) return true 39/compare %ecx 2/r32/edx 7d/jump-if-greater-or-equal $array-equal?:true/disp8 # var vala/eax : int = *curra 8b/-> *esi 0/r32/eax # var valb/ebx : int = *currb 8b/-> *edi 3/r32/ebx # if (vala != valb) return false 39/compare %eax 3/r32/ebx 75/jump-if-not-equal $array-equal?:false/disp8 # i += 4 81 0/subop/add %ecx 4/imm32 # currs += 4 81 0/subop/add %esi 4/imm32 # currb += 4 81 0/subop/add %edi 4/imm32 eb/jump $array-equal?:loop/disp8 $array-equal?:true: b8/copy-to-eax 1/imm32 eb/jump $array-equal?:end/disp8 $array-equal?:false: b8/copy-to-eax 0/imm32 $array-equal?:end: # . restore registers 5f/pop-to-edi 5e/pop-to-esi 5b/pop-to-ebx 5a/pop-to-edx 59/pop-to-ecx # . epilogue 89/<- %esp 5/r32/ebp 5d/pop-to-ebp c3/return test-compare-empty-with-empty-array: # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp # var ecx : (array _) = [] 68/push 0/imm32/size 89/<- %ecx 4/r32/esp # var edx : (array _) = [] 68/push 0/imm32/size 89/<- %edx 4/r32/esp # eax = array-equal?(ecx, edx) # . . push args 52/push-edx 51/push-ecx # . . call e8/call array-equal?/disp32 # . . discard args 81 0/subop/add %esp 8/imm32 # check-ints-equal(eax, 1, msg) # . . push args 68/push "F - test-compare-empty-with-empty-array"/imm32 68/push 1/imm32/true 50/push-eax # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add %esp 0xc/imm32 # . epilogue 89/<- %esp 5/r32/ebp 5d/pop-to-ebp c3/return test-compare-empty-with-non-empty-array: # also checks length-mismatch code path # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp # var ecx : (array int) = [1] 68/push 1/imm32 68/push 4/imm32/size 89/<- %ecx 4/r32/esp # var edx : (array int) = [] 68/push 0/imm32/size 89/<- %edx 4/r32/esp # eax = array-equal?(ecx, edx) # . . push args 52/push-edx 51/push-ecx # . . call e8/call array-equal?/disp32 # . . discard args 81 0/subop/add %esp 8/imm32 # check-ints-equal(eax, 0, msg) # . . push args 68/push "F - test-compare-empty-with-non-empty-array"/imm32 68/push 0/imm32/false 50/push-eax # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add %esp 0xc/imm32 # . epilogue 89/<- %esp 5/r32/ebp 5d/pop-to-ebp c3/return test-compare-equal-arrays: # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp # var ecx : (array int) = [1, 2, 3] 68/push 3/imm32 68/push 2/imm32 68/push 1/imm32 68/push 0xc/imm32/size 89/<- %ecx 4/r32/esp # var edx : (array int) = [1, 2, 3] 68/push 3/imm32 68/push 2/imm32 68/push 1/imm32 68/push 0xc/imm32/size 89/<- %edx 4/r32/esp # eax = array-equal?(ecx, edx) # . . push args 52/push-edx 51/push-ecx # . . call e8/call array-equal?/disp32 # . . discard args 81 0/subop/add %esp 8/imm32 # check-ints-equal(eax, 1, msg) # . . push args 68/push "F - test-compare-equal-arrays"/imm32 68/push 1/imm32/true 50/push-eax # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add %esp 0xc/imm32
<!-- Provide a descriptive summary of the changes in the title above -->

#### ISSUE TYPE
<!-- Pick relevant types and delete the rest -->
- Bug fix
- Improvement/feature implementation
- Breaking changes

#### RUNTIME ENVIRONMENT
<!-- Details of your runtime environment -->
<!-- Retrieve Python/ranger version and locale with `ranger -\-version` -->
- Operating system and version: 
- Terminal emulator and version: 
- Python version: 
- Ranger version/commit: 
- Locale: 

#### CHECKLIST
<!-- All [REQUIRED] requisites need to be fulfilled -->
<!-- Replace [ ] with [X] when fulfilled -->
- [ ] The `CONTRIBUTING` document has been read **[REQUIRED]**
- [ ] All changes follow the code style **[REQUIRED]**
- [ ] All new and existing tests pass **[REQUIRED]**
- [ ] Changes require config files to be updated
    - [ ] Config files have been updated
- [ ] Changes require documentation to be updated
    - [ ] Documentation has been updated
- [ ] Changes require tests to be updated
    - [ ] Tests have been updated

#### DESCRIPTION
<!-- Describe the changes in detail -->


#### MOTIVATION AND CONTEXT
<!-- Why are these changes required? -->
<!-- What problems do these changes solve? -->
<!-- Link to relevant issues -->


#### TESTING
<!-- What tests have been run? -->
<!-- How does the changes affect other areas of the codebase? -->


#### IMAGES / VIDEOS<!-- Only if relevant -->
<!-- Link or embed images and videos of screenshots, sketches etc. -->
dd %esp 8/imm32 # check-ints-equal(*eax, 0, msg) # . . push args 68/push "F - test-parse-array-of-ints-empty"/imm32 68/push 0/imm32/size ff 6/subop/push *eax # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add %esp 0xc/imm32 # . epilogue 89/<- %esp 5/r32/ebp 5d/pop-to-ebp c3/return test-parse-array-of-ints-extra-whitespace: # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp # var ecx : (array int) = [1, 2, 3] 68/push 3/imm32 68/push 2/imm32 68/push 1/imm32 68/push 0xc/imm32/size 89/<- %ecx 4/r32/esp # eax = parse-array-of-ints(Heap, " 1 2 3 ") # . . push args 68/push " 1 2 3 "/imm32 68/push Heap/imm32 # . . call e8/call parse-array-of-ints/disp32 # . . discard args 81 0/subop/add %esp 8/imm32 # eax = array-equal?(ecx, eax) # . . push args 50/push-eax 51/push-ecx # . . call e8/call array-equal?/disp32 # . . discard args 81 0/subop/add %esp 8/imm32 # check-ints-equal(eax, 1, msg) # . . push args 68/push "F - test-parse-array-of-ints-extra-whitespace"/imm32 68/push 1/imm32/true 50/push-eax # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add %esp 0xc/imm32 # . epilogue 89/<- %esp 5/r32/ebp 5d/pop-to-ebp c3/return # helper for later tests # compare an array with a string representation of an array literal check-array-equal: # a : (addr array int), expected : (addr string), msg : (addr string) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp # . save registers 50/push-eax # var b/ecx : (handle array int) = parse-array-of-ints(Heap, expected) # . eax = parse-array-of-ints(Heap, expected) # . . push args ff 6/subop/push *(ebp+0xc) 68/push Heap/imm32 # . . call e8/call parse-array-of-ints/disp32 # . . discard args 81 0/subop/add %esp 8/imm32 # . b = eax 89/<- %ecx 0/r32/eax # eax = array-equal?(a, b) # . . push args 51/push-ecx ff 6/subop/push *(ebp+8) # . . call e8/call array-equal?/disp32 # . . discard args 81 0/subop/add %esp 8/imm32 # check-ints-equal(eax, 1, msg) # . . push args ff 6/subop/push *(ebp+0x10) 68/push 1/imm32 50/push-eax # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add %esp 0xc/imm32 $check-array-equal:end: # . restore registers 58/pop-to-eax # . epilogue 89/<- %esp 5/r32/ebp 5d/pop-to-ebp c3/return test-check-array-equal: # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp # var ecx : (array int) = [1, 2, 3] 68/push 3/imm32 68/push 2/imm32 68/push 1/imm32 68/push 0xc/imm32/size 89/<- %ecx 4/r32/esp # check-array-equal(ecx, "1 2 3", "msg") # . . push args 68/push "F - test-check-array-equal"/imm32 68/push "1 2 3"/imm32 51/push-ecx # . . call e8/call check-array-equal/disp32 # . . discard args 81 0/subop/add %esp 8/imm32 # . epilogue 89/<- %esp 5/r32/ebp 5d/pop-to-ebp c3/return # . . vim:nowrap:textwidth=0