Re: x86 assembly language -
I have three 32-bit signed numbers: n1, n2, and n3.
I want to imul n1 by n2 to get a 64-bit signed result.
I then want to idiv that 64-bit result by n3.
The problem is that if the 64-bit signed result is large enough and/or if n3 is small enough, an overflow will result and idiv will throw a #DE exception.
If idiv simply set #DE on overflow, I could check to confirm that ((n1 * n2) / n3) * n3 + ((n1 * n2) mod n3) = (n1 * n2). If not, overflow would have occurred and I could proceed accordingly.
But #DE does not play nice with others. When it's raised, it reports "Program has stopped working" and then kicks you out.
So i either need to find some way of pre-checking whether an idiv will cause an overflow before I do the division, or I need to do the equivalent of a try ... catch in assembly language.
I've searched the internet (including here) and find very little on this in general; and nothing that is particularly useful.
I've tried inlining the code inside a c++ try ... catch to no avail - it still reports "Program has stopped working" and then kicks you out.
For example, with the two supporting files:
// TC.h
// Version 1.0.0
// MDJ 2016/05/06
extern "C" int q;
extern "C" int m;
and
// TC.s
// Version 1.0.0
// MDJ 2016/05/06
.globl _q
.globl _m
.bss
.align 4
_q:
.space 4
_m:
.space 4
this file runs to completion and produces the correct results:
// TryCatch.cpp
// Version 1.0.0
// MDJ 2016/05/06
#include <iostream>
#include "TC.h"
using namespace std;
int main() {
cout << endl;
try {
# AT&T syntax
asm(
"movl $34, %eax\n\t"
"movl $48, %edx\n\t"
"imull %edx\n\t"
"movl $13, %ecx\n\t"
"idivl %ecx\n\t"
"movl %eax, _q\n\t"
"movl %edx, _m\n\t"
);
}
catch(int e) {
cout << "Caught." << endl;
}
cout << "Reached the End." << endl;
cout << "q = " << q << endl;
cout << "m = " << m << endl;
cout << endl;
return 0;
}
But, if I change n1, n2, and n3 like this:
// TryCatch.cpp
// Version 1.0.0
// MDJ 2016/05/06
#include <iostream>
#include "TC.h"
using namespace std;
int main() {
cout << endl;
try {
# AT&T syntax
asm(
"movl $234567890, %eax\n\t"
"movl $123456789, %edx\n\t"
"imull %edx\n\t"
"movl $3, %ecx\n\t"
"idivl %ecx\n\t"
"movl %eax, _q\n\t"
"movl %edx, _m\n\t"
);
}
catch(int e) {
cout << "Caught." << endl;
}
cout << "Reached the End." << endl;
cout << "q = " << q << endl;
cout << "m = " << m << endl;
cout << endl;
return 0;
}
the "catch" doesn't catch the overflow and the system instead reports "Program has stopped working" and then kicks you out.
Any help would be appreciated.