Let's say I have $t0
, and I'd like to divide its integer contents by two, and store it in $t1
.
My gut says: srl $t1, $t0, 2
... but wouldn't that be a problem if... say... the right-most bit was 1? Or does it all come out in the wash because the right-most bit (if positive) makes $t0
an odd number, which becomes even when divided?
Teach me, O wise ones...
Use instruction sra: Shift right arithmetic !!
sra $t1, $t0, 1
Divides the content of $t0 by the first power of 2.
Description: Shifts a register value right by the shift amount (shamt) and places the value in the destination register. The sign bit is shifted in.
Operation: $d = $t >> h;
advance_pc (4);
Syntax: sra $d, $t, h
Encoding: 0000 00-- ---t tttt dddd dhhh hh00 0011
Why is this important? Check this simple program that divides an integer number (program's input) by 2.
#include <stdio.h>
/*
* div divides by 2 using sra
* udiv divides by 2 using srl
*/
int div(int n);//implemented in mips assembly.
int udiv(int n);
int main(int argc,char** argv){
if (argc==1) return 0;
int a = atoi(argv[1]);
printf("div:%d udiv:%d\n",div(a),udiv(a));
return 1;
}
//file div.S
#include <mips/regdef.h>
//int div(int n)
.globl div
.text
.align 2
.ent div
div:
sra v0,a0,1
jr ra //Returns value in v0 register.
.end div
//int udiv(int n)
.globl udiv
.text
.align 2
.ent udiv
udiv: srl v0,a0,1 jr ra //Returns value in v0 register. .end udiv
Compile
root@:/tmp#gcc -c div.S
root@:/tmp#gcc -c main.c
root@:/tmp#gcc div.0 main.o -o test
Test drives:
root@:~# ./test 2
div:1 udiv:1
root@:~# ./test 4
div:2 udiv:2
root@:~# ./test 8
div:4 udiv:4
root@:~# ./test 16
div:8 udiv:8
root@:~# ./test -2
div:-1 udiv:2147483647
root@:~# ./test -4
div:-2 udiv:2147483646
root@:~# ./test -8
div:-4 udiv:2147483644
root@:~# ./test -16
div:-8 udiv:2147483640
root@:~#
See what happens? The srl instruction is shifting the sign bit
-2 = 0xfffffffe
if we shift one bit to the right, we get 0x7fffffff
0x7ffffffff = 2147483647
Of course this is not a problem when the number is a positive integer, because the sign bit is 0.