【发布时间】:2012-01-29 11:50:24
【问题描述】:
对不起我的英语不好
我正在努力提高我的 asm 能力,我发现很容易 使用机器代码例程处理它的入口点 来自c代码
我就是这样用的
char asmRoutineData2[] =
{
0xC8, 0x00, 0x00, 0x00, // enter 0, 0
0xB8, 0xff, 0x00 ,0x00 ,0x00, // mov eax, 65538
0xC9, // leave
0xc3 // ret
};
int (*asmRoutine)(void) = (int (*)(void)) asmRoutineData;
int ret = asmRoutine();
对于某些例程来说效果非常好 - 例如上面
其他一些不起作用:
1)我遇到了麻烦,我无法获取堆栈传递的值
这样的程序
char asmRoutine_body[] =
{
0xC8, 0x00, 0x00, 0x00, //enter
0x8B, 0x45, 0x08, // mov eax, [ebp+8]
0xC9, //leave
0xC3
};
和
int ( *asmRoutine)(int, int, int) = ( int (*)(int, int, int)) asmRoutine_body;
int ret = asmRoutine(77,66,55);
据我所知应该有效,但它没有
我在 kompiler 生成的 asm 中查找,它似乎是正确的
mov eax,offset _asmRoutineData
push 55
push 66
push 77
call eax
add esp,12
_asmRoutineData label byte
db 200 //enter
db 0
db 0
db 0
db 139 // mov eax, dword [ebp+8H] ; 8B. 45, 08
db 69
db 8
db 201 //leave
db 195 //ret
不知道出了什么问题(返回我预期的 77 以外的其他值(对于 ebp+12 ebp+16 或 66 或 55)
2) 第二个麻烦是这种调用机器码的方式 适用于我的算术指令,但它会使应用程序崩溃 (某种方式的系统异常)在 fpu 或 sse 指令上
为什么?以及我应该怎么做才能使它对我有用(我很想写汇编 例程这样)
冷杉
//编辑
这是 sse 例程,应该得到一个 float4* 向量 a 和 b 制作点积并将结果放入 float4* c (float4 是 4 个浮点数的结构或表)
(奇怪的是它应该只得到两个向量并返回一个浮点数 通过 eax 但我得到了如果可能形成互联网并且没有时间 测试并重写)
/*
enter 0, 0 ; 0034 _ C8, 0000, 00
mov eax, dword [ebp+8H] ; 0038 _ 8B. 45, 08
mov ebx, dword [ebp+0CH] ; 003B _ 8B. 5D, 0C
mov ecx, dword [ebp+10H] ; 003E _ 8B. 4D, 10
movups xmm0, oword [eax] ; 0041 _ 0F 10. 00
movups xmm1, oword [ebx] ; 0044 _ 0F 10. 0B
mulps xmm0, xmm1 ; 0047 _ 0F 59. C1
movhlps xmm1, xmm0 ; 004A _ 0F 12. C8
addps xmm1, xmm0 ; 004D _ 0F 58. C8
movaps xmm0, xmm1 ; 0050 _ 0F 28. C1
shufps xmm1, xmm1, 1 ; 0053 _ 0F C6. C9, 01
addss xmm0, xmm1 ; 0057 _ F3: 0F 58. C1
movss dword [ecx], xmm0 ; 005B _ F3: 0F 11. 01
leave ; 005F _ C9
ret ; 0060 _ C3
*/
char asmDot_body[] =
{
0xC8, 0x00, 0x00, 0x00,
0x8B, 0x45, 0x08,
0x8B, 0x5D, 0x0C,
0x8B, 0x4D, 0x10,
0x0F, 0x10, 0x00,
0x0F, 0x10, 0x0B,
0x0F, 0x59, 0xC1,
0x0F, 0x12, 0xC8,
0x0F, 0x58, 0xC8,
0x0F, 0x28, 0xC1,
0x0F, 0xC6, 0xC9, 0x01,
0xF3, 0x0F, 0x58, 0xC1,
0xF3, 0x0F, 0x11, 0x01,
0xC9,
0xC3
};
void (*asmAddSSE)(float4*, float4*, float4*) = (void (*)(float4*, float4*, float4*)) asmDot_body;
float4 a = {1,2,1,0};
float4 b = {1,2,3,0};
float4 c = {0,0,0,0};
asmAddSSE(&a,&b,&c);
//编辑 L8R
找到了!它非常酷而且很棒 (传递参数以及 fpu 甚至 sse) 我很高兴
tnx necrolis 表示它正在你的系统上运行,
我开始尝试用编译器开关 tu 设置对齐和 也禁用一些,它是 -pr (使用 fastcall ) 已启用,我应该将其关闭
(有两个 compile.bat - 一个用于正常编译和 第二个用于 olso 生成程序集,并且在 第二个所以我写的asm代码还可以 - 但我的正常 compile.bat 生成的 fastcall 调用 ant 它会出错!)
【问题讨论】:
-
您没有使用汇编程序。您正在编写机器代码。获取汇编程序。
-
如何在调试器中逐条指令执行代码?这会告诉你你的代码有什么问题。
-
没有调试器:/我也知道我正在编写机器代码 - 没有内联汇编,也不想与独立汇编作斗争(它要复杂得多)一些其他的如何调试和修理它?我不知道怎么了
-
@user982377 你刚才是不是说汇编比写机器代码更复杂?
标签: c assembly x86 calling-convention