我使用Intel x86进行汇编编程。我有两个变量(int),我希望汇编程序函数返回最大值。我用C程序调用汇编程序函数,我在main()函数(1,5)中得到了它。
这是汇编代码:
.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
最大的数字将是%eax(movl var2,%eax)。问题是 该函数始终返回%eax中的初始数字。 例如,函数(1,5)返回“1”而不是“5”。
我不明白为什么结果出错了。
编辑:感谢您的回复,我已根据您的建议修改了该计划:
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
要回到function()
,我使用jmp
,这是正确的吗?
它工作正常。
另外,我该如何改进此代码?我使用变量,因为目标是有三个数字并找到中位数。
答案 0 :(得分:2)
我认为您对jg
和jl
说明正在做什么感到困惑。
从你的代码中,我最好的猜测是你认为它们大致相当于这个C代码:
if (condition) cond1();
而他们实际上表现得像
if (condition) goto cond1;
因此,您的函数有三种可能的控制流路径:
1)如果采用jg
分支:
----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)如果未采用jg
分支,但采用jl
分支:
----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)如果两个分支都没有 - 这是执行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----'
答案 1 :(得分:1)
好吧,我不是很熟悉NASM格式(我使用MASM),而且我有一段时间没有完成x86程序集,但看起来你回来的样子并不像你的函数中的任何东西(cdecl调用约定我假设)。您需要将返回值推送到堆栈,然后执行“ret 4”或类似的操作。
答案 2 :(得分:1)
函数返回的值通常在EAX寄存器中返回,在您加载它之后,它永远不会改变(只更改“var1”和“var2”)。
对于简化版本(没有“var1”和“var2”):
function:
movl 4(%esp), %eax /* EAX = a */
cmpl 8(%esp), %eax /* Is a >= b? */
jge done /* yes, return a (already in EAX) */
movl 8(%esp), %eax /* no, return b */
done:
ret