内联汇编代码求助

麦田追风 2010-01-04 10:09:54
我这有个C语言内联汇编的代码,现在编译器不支持内联汇编关键字
小弟不懂汇编,麻烦大侠帮我解释下下面内联汇编代码,最好是改写成C
小弟不胜感激

WORD cmsLinearInterpLUT16(WORD Value, WORD LutTable[], LPL16PARAMS p)
{
int xDomain = p -> Domain;


if (Value == 0xffff) return LutTable[p -> Domain];
else
__asm {
xor eax, eax
mov ax, word ptr ss:Value
mov edx, ss:xDomain
mul edx // val3 = p -> Domain * Value;
shld edx, eax, 16 // Convert it to fixed 15.16
shl eax, 16 // * 65536 / 65535
mov ebx, 0x0000ffff
div ebx
mov ecx, eax
sar ecx, 16 // ecx = cell0
mov edx, eax // rest = (val2 & 0xFFFFU)
and edx, 0x0000ffff // edx = rest
mov ebx, ss:LutTable
lea eax, dword ptr [ebx+2*ecx] // Ptr to LUT
xor ebx, ebx
mov bx, word ptr [eax] // EBX = y0
movzx eax, word ptr [eax+2] // EAX = y1
sub eax, ebx // EAX = y1-y0
js IsNegative
mul edx // EAX = EAX * rest
shld edx, eax, 16 // Pass it to fixed
sal eax, 16 // * 65536 / 65535
mov ecx, 0x0000ffff
div ecx
add eax, 0x8000 // Rounding
sar eax, 16
add eax, ebx // Done!
}

RET((WORD) _EAX);

IsNegative:

__asm {
neg eax
mul edx // EAX = EAX * rest
shld edx, eax, 16 // Pass it to fixed
sal eax, 16 // * 65536 / 65535
mov ecx, 0x0000ffff
div ecx
sub eax, 0x8000
neg eax
sar eax, 16
add eax, ebx // Done!
}

RET((WORD) _EAX);
}
...全文
105 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
麦田追风 2010-01-05
  • 打赏
  • 举报
回复
麻烦帮我看下这个代码改写对不对,谢谢,请多多关照,分不够再加
Fixed32是long类型,32位

汇编语言:
WORD FixedScale(WORD a, Fixed32 s)
{
ASM {

xor eax,eax
mov ax, ss:a
sal eax, 16
mov edx, ss:s
mul edx
add eax, 0x8000
adc edx, 0
mov eax, edx
}

RET(_EAX);
}
C语言:
WORD FixedScale(WORD a, Fixed32 s)
{
return (WORD)((a*65536*s+0x8000) >> 32);
}
麦田追风 2010-01-05
  • 打赏
  • 举报
回复
然后取数组这块没能理解,它是根据什么判断要取数组里面的值~~~?

mov ebx, ss:LutTable
lea eax, dword ptr [ebx+2*ecx] // Ptr to LUT
xor ebx, ebx
mov bx, word ptr [eax] // EBX = y0
movzx eax, word ptr [eax+2] // EAX = y1
麦田追风 2010-01-05
  • 打赏
  • 举报
回复
TO:cnzdgs

lea eax, dword ptr [ebx+2*ecx] // Ptr to LUT
这行代码是把ebx+2*ecx的地址传给eax吧,前面的dword 是把值转成无符号长整形吗
cnzdgs 2010-01-05
  • 打赏
  • 举报
回复
#4:lea eax, dword ptr [ebx+2*ecx]是把ebx+2*ecx给eax,前面的dword ptr不起作用。
#5:这段代码就是取LutTable数组中两个相临元素,至于“根据什么判断要取数组里面的值”是逻辑上的问题,从代码中看不出。
#6:Fixed32是什么类型?如果是32位整数则上面写法是对的,只是有些冗余代码(其实帖子问题中的代码也有很多冗余)。你可以用C语言编译然后反汇编来看汇编代码。
cnzdgs 2010-01-04
  • 打赏
  • 举报
回复
WORD cmsLinearInterpLUT16(WORD Value, WORD LutTable[], LPL16PARAMS p)
{
WORD xDomain = (WORD)p->Domain;
if (Value != -1)
{
DWORD d = (DWORD)((ULONGLONG)xDomain * Value * 0x10000 / 0xFFFF);
WORD w1 = (WORD)(d >> 16);
WORD w2 = (WORD)d;
long l = (long)LutTable[w1+1] - (long)LutTable[w1];
return (WORD)((((LONGLONG)l * w2 * 0x10000 / 0xFFFF + 0x8000) >> 16) + LutTable[w1]);
}
return LutTable[xDomain];
}
cnzdgs 2010-01-04
  • 打赏
  • 举报
回复
if (Value != 65535)
对。我以便习惯写成-1,这里应该是if (Value != (WORD)-1),写的时候没注意。

汇编中数组下标要自己根据数组类型计算计算,WORD型占2字节,所以用+0、+2、+4、+6……的形式。

and edx, 0x0000ffff是取低16位,WORD型只有16位,转换为WORD型时高位自动丢弃了。
麦田追风 2010-01-04
  • 打赏
  • 举报
回复
TO:LS
谢谢cnzdgs的帮忙!

不好意思有些地方没写明白,我代码里的WORD是unsigned short类型
应该是:
if (Value != 65535)
{....}
吧~~~?

请问下面两行代码是从数组中取值吗,汇编是寄存器操作能自动识别数组的下标吗

mov bx, word ptr [eax] // EBX = y0
movzx eax, word ptr [eax+2] // EAX = y1

还有
and edx, 0x0000ffff // edx = rest
这行代码是取edx的低位吧,那么w2是不是要取d的低位啊

21,458

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧