I use Intel x86 for assembler programming. I've got two variables (int), and I want the assembler function to return the biggest. I call the assembler function with a C program, and I've got this in the main(), function(1,5).
Here is the assembler code:
.globl function
.data
var1: .long 0
var2: .long 0
.text
function:
movl 4(%esp), %eax
movl 8(%esp), %ebx
cmp %eax, %ebx
jg cond1 /*greater, if a < b */
jl cond2 /*lower, if a > b */
movl var2, %eax
ret
cond1:
movl %eax, var1 /*var1 = a */
movl %ebx, var2 /*var2 = b */
ret
cond2:
movl %eax, var2 /*var2 = a*/
movl %ebx, var1 /*var1 = b */
ret
The biggest number will be in %eax (movl var2, %eax). The problem is that the function always returns the initial number in %eax. For example, function(1,5) returns "1" instead of "5".
I don't understand why the result is wrong.
EDIT : Thanks to your replies, I've modified the program thanks to your advice :
function:
movl 4(%esp), %eax
movl 8(%esp), %ebx
cmp %eax, %ebx
jg cond1 /*greater, if a < b */
jl cond2 /*lower, if a > b */
next:
movl var2, %eax
ret
cond1:
movl %eax, var1 /*var1 = a */
movl %ebx, var2 /*var2 = b */
jmp next
cond2:
movl %eax, var2 /*var2 = a*/
movl %ebx, var1 /*var1 = b */
jmp next
To come-back in function()
, I use jmp
, is it correct?
It works fine.
Also, how can I improve this code? I use variables because the aim will be to have three numbers and find the median one.
I think you're confused about what the jg
and jl
instructions are doing.
From your code, my best guess is that you're thinking of them as being approximately equivalent to this C code:
if (condition) cond1();
whereas they actually behave like
if (condition) goto cond1;
So, there are three possible control flow paths through your function:
1) If the jg
branch is taken:
----caller----.
|
v
function:
movl 4(%esp), %eax
movl 8(%esp), %ebx
cmp %eax, %ebx
jg cond1 /*greater, if a < b */
|
branch
|
v
cond1:
movl %eax, var1 /*var1 = a */
movl %ebx, var2 /*var2 = b */
ret
|
return to |
<---caller----'
2) If the jg
branch is not taken, but the jl
branch is taken:
----caller----.
|
v
function:
movl 4(%esp), %eax
movl 8(%esp), %ebx
cmp %eax, %ebx
jg cond1 /*greater, if a < b */
jl cond2 /*lower, if a > b */
|
branch
|
v
cond2:
movl %eax, var2 /*var2 = a*/
movl %ebx, var1 /*var1 = b */
ret
|
return to |
<---caller----'
3) If neither branch is taken -- this is the only path which executes movl var2, %eax
:
----caller----.
|
v
function:
movl 4(%esp), %eax
movl 8(%esp), %ebx
cmp %eax, %ebx
jg cond1 /*greater, if a < b */
jl cond2 /*lower, if a > b */
movl var2, %eax
ret
|
return to |
<---caller----'