Reverse Engineering for Beginners

(avery) #1

CHAPTER 24. 64-BIT VALUES IN 32-BIT ENVIRONMENT CHAPTER 24. 64-BIT VALUES IN 32-BIT ENVIRONMENT


sltu $a1, $v1
jr $ra
; subtract 1 from high part of result if carry should be generated:
subu $v0, $a1 ; branch delay slot
; $v0 - high part of result
; $v1 - low part of result


f_add_test:


var_10 = -0x10
var_4 = -4


lui $gp, (__gnu_local_gp >> 16)
addiu $sp, -0x20
la $gp, (__gnu_local_gp & 0xFFFF)
sw $ra, 0x20+var_4($sp)
sw $gp, 0x20+var_10($sp)
lui $a1, 0x73CE
lui $a3, 0x7593
li $a0, 0xB3A
li $a3, 0x75939F79
li $a2, 0x1555
jal f_add
li $a1, 0x73CE2FF2
lw $gp, 0x20+var_10($sp)
lui $a0, ($LC0 >> 16) # "%lld\n"
lw $t9, (printf & 0xFFFF)($gp)
lw $ra, 0x20+var_4($sp)
la $a0, ($LC0 & 0xFFFF) # "%lld\n"
move $a3, $v1
move $a2, $v0
jr $t9
addiu $sp, 0x20

$LC0: .ascii "%lld\n"<0>


MIPS has no flags register, so there is no such information present after the execution of arithmetic operations. So there are
no instructions like x86’s ADC and SBB. To know if the carry flag would be set, a comparison (using “SLTU” instruction) also
occurs, which sets the destination register to 1 or 0. This 1 or 0 is then added or subtracted to/from the final result.


24.3 Multiplication, division.


#include <stdint.h>


uint64_t f_mul (uint64_t a, uint64_t b)
{
return a*b;
};


uint64_t f_div (uint64_t a, uint64_t b)
{
return a/b;
};


uint64_t f_rem (uint64_t a, uint64_t b)
{
return a % b;
};


24.3.1 x86


Listing 24.9: Optimizing MSVC 2013 /Ob1

_a$ = 8 ; size = 8
_b$ = 16 ; size = 8

Free download pdf