2

Can anyone help me convert following x86 inline asm code to arm format?

bool N_FLAG = 0;
bool C_FLAG = 0;
bool Z_FLAG = 0;
bool V_FLAG = 0;

asm  ("sub %1, %%ebx;"\
"setsb N_FLAG;"\
"setzb Z_FLAG;"\
"setncb C_FLAG;"\
"setob V_FLAG;"\
: "=b" (reg[dest].I)\
: "r" (reg[base].I), "b" (value));

2 Answers 2

2

How about converting this into C?

It looks like the code subtracts two numbers (value - reg[base].I), stores the result into reg[dest].I and then checks the various flags.

So something (roughly, not tested) like:

reg[dest].I = value - reg[base].I;
Z_FLAG = (reg[dest].I == 0);
N_FLAG = (reg[dest].I < 0);
/* repeat for: carry, overflow */

And then let the compiler do its magic? The ARM gcc compiler is not bad in mapping this sort of stuff to the right ARM instructions.

If you want to go ARM assembly you're probably looking at using conditional move instructions, something like (wrote quickly - untested):

__asm__ (
"subs %[out], %[in2], %[in1]\n\t"
"movmi %[N_FLAG], #1\n\t"
"moveq %[Z_FLAG], #1\n\t"
"movcs %[C_FLAG], #1\n\t"
"movvs %[V_FLAG], #1\n\t"
: [N_FLAG]"+r"(N_FLAG), [Z_FLAG]"+r"(Z_FLAG), [C_FLAG]"+r"(C_FLAG), [V_FLAG]"+r"(V_FLAG), [out]"=r" (reg[dest].I)
: [in1]"r" (reg[base].I), [in2]"r"(value))
: "cc"
);
Sign up to request clarification or add additional context in comments.

6 Comments

thanks, it works. And thanks to you that I know what does '[]' means now :) but I still doubt when "movmi %[N_FLAG], #1\n\t" fails, the N_FLAG will be set with 0.
@KarlYu: movmi can't fail. It will move 1 into N_FLAG if the number is negative. If it positive it will be 0. That is the same function performed by setsb in the x86 assembly. If this answer is correct and has helped you please accept it!
No, this will not set any flag variable to 0, it will leave them unchanged.
@TimothyBaldwin If you look at the question you'll see the flag variable is initialized to zero so leave as unchanged (zero) is what the person asking was looking for...
@TimothyBaldwin: I saw your proposed edit and I agree. The sub needs to be subs...
|
1

This code works for me using clang:

int sub(int a, int b)
{
  int c;
  asm ("sub %0, %2, %1" : "=r" (c) : "r" (b), "r" (a));
  return c;
}

Notice the commas between the register arguments.

3 Comments

thank you for answering. but still can't pass step link, can you try with xcode gcc4.2?
Works for me in gcc 4.2.1. Looking at the disassembly, it didn't produce anything that wouldn't link. I bet you're hitting a relocation error due to fixed offsets. What's the linker error?
it seams to be problem of my code not the arm code itself, thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.