在线等待,VC中嵌入汇编的问题......

PlayerBox 2003-09-13 10:00:39
typedef struct stu{
char name[50];
int no;
};
如何把这个函数中所有的代码改成汇编.

stu* foo(int nCount,stu student)
{
stu* stuArr=new stu[nCount];
.....
return stuArr;
}
stu* foo(int nCount,stu student)
{
_asm{
?????
????????????????????????
}
}
我的目的是想知道如何用汇编实现动态分配内存的功能,请高手不吝赐教.一定给分.
...全文
62 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaohedou 2003-11-12
  • 打赏
  • 举报
回复
AthlonxpX86(一滴水) 和gzshd 都好久不见了!两位我都很佩服!AthlonxpX86,在硬件区里也是高手!
xf_lii 2003-11-09
  • 打赏
  • 举报
回复

typedef struct {
char name[50];
int no;
} stu;

stu* foo(int nCount,stu student)
{

stu* stu1;
_asm
{
mov eax, nCount
imul eax,eax,38h
push eax
call new
add esp,4
mov stu1, eax
}
return stu1;
}

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
stu stud;
foo (5, stud);
return 0;
}
xf_lii 2003-11-09
  • 打赏
  • 举报
回复
PlayerBox((())):
我给你解决了问题你为什么不给我分?
不公平,我反对,
我......
xf_lii 2003-11-09
  • 打赏
  • 举报
回复
stu* foo(int nCount,stu student)
{
_asm{
stu* stu1;
_asm
{
mov eax, nCount
imul eax,eax,38h
push eax
call new
add esp,
mov stu1, eax
}
return stuArr;
}

--> 38h 是你的stu的大小, 即sizeof的返回值.
由于sizeof()是在编译时完成的,所以不能用在_asm{ }里.
不过你也可以这样: int i = sizeof(stu); _asm{imul eax,eax,i }



PlayerBox 2003-11-09
  • 打赏
  • 举报
回复
up
PlayerBox 2003-10-12
  • 打赏
  • 举报
回复
多谢AthlonxpX86(一滴水):
dzq138 2003-09-19
  • 打赏
  • 举报
回复
UP
AthlonxpX86 2003-09-19
  • 打赏
  • 举报
回复
#include "stdafx.h"

int main(int argc, char* argv[])
{
int *p=new int[100];
delete [] p;
return 0;

}
下面是这段代码的汇编代码,用MASM 6以上版本可以直接编译




; Listing generated by Microsoft (R) Optimizing Compiler Version 12.00.9044.0

TITLE F:\编程开发\程序设计\VC C C++\我的作品\new\new.cpp
.386P
include listing.inc
if @Version gt 510
.model FLAT
else
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
_DATA SEGMENT DWORD USE32 PUBLIC 'DATA'
_DATA ENDS
CONST SEGMENT DWORD USE32 PUBLIC 'CONST'
CONST ENDS
_BSS SEGMENT DWORD USE32 PUBLIC 'BSS'
_BSS ENDS
$$SYMBOLS SEGMENT BYTE USE32 'DEBSYM'
$$SYMBOLS ENDS
$$TYPES SEGMENT BYTE USE32 'DEBTYP'
$$TYPES ENDS
_TLS SEGMENT DWORD USE32 PUBLIC 'TLS'
_TLS ENDS
; COMDAT _main
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
FLAT GROUP _DATA, CONST, _BSS
ASSUME CS: FLAT, DS: FLAT, SS: FLAT
endif

INCLUDELIB LIBCD
INCLUDELIB OLDNAMES

PUBLIC _main
EXTRN ??2@YAPAXI@Z:NEAR ; operator new
EXTRN ??3@YAXPAX@Z:NEAR ; operator delete
EXTRN __chkesp:NEAR
; Function compile flags: /Odt /GZ /ZI
; File F:\编程开发\程序设计\VC C C++\我的作品\new\new.cpp
; COMDAT _main
_TEXT SEGMENT
_p$ = -4
$T589 = -8
$T590 = -12
_main PROC NEAR ; COMDAT

; 7 : {

push ebp
mov ebp, esp
sub esp, 76 ; 0000004cH
push ebx
push esi
push edi
lea edi, DWORD PTR [ebp-76]
mov ecx, 19 ; 00000013H
mov eax, -858993460 ; ccccccccH
rep stosd

; 8 : int *p=new int[100];

push 400 ; 00000190H
call ??2@YAPAXI@Z ; operator new
add esp, 4
mov DWORD PTR $T589[ebp], eax
mov eax, DWORD PTR $T589[ebp]
mov DWORD PTR _p$[ebp], eax

; 9 : delete [] p;

mov eax, DWORD PTR _p$[ebp]
mov DWORD PTR $T590[ebp], eax
mov ecx, DWORD PTR $T590[ebp]
push ecx
call ??3@YAXPAX@Z ; operator delete
add esp, 4

; 10 : return 0;

xor eax, eax

; 11 :
; 12 : }

pop edi
pop esi
pop ebx
add esp, 76 ; 0000004cH
cmp ebp, esp
call __chkesp
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END

如果想自己写new delete的代码,你可以debug单步调试来看他的源代码
zxwitsme 2003-09-19
  • 打赏
  • 举报
回复
C++ 把局部变量放在堆栈中,全局、静态变量放在堆中,
分配内存以后编译成汇编系统就会根据指定的内存来操作数据
而直接用汇编来写程序是不需要这样的分配内存的,因为汇编语言直接指明了
使用的堆栈吧,我的理解:)
Onega 2003-09-19
  • 打赏
  • 举报
回复
用new分配的东西,一定要用delete释放。不能混用。
xiaohedou 2003-09-14
  • 打赏
  • 举报
回复
关于汇编可以参考罗云彬的主页!

名称:罗云彬的编程乐园
http://asm.yeah.net
PlayerBox 2003-09-14
  • 打赏
  • 举报
回复
up
PlayerBox 2003-09-14
  • 打赏
  • 举报
回复
难道没有人知道怎样把这两句
stu* stuArr=new stu[nCount];
return stuArr;
改成汇编吗?

:(
chen_pin 2003-09-14
  • 打赏
  • 举报
回复
Up it
zuolihua 2003-09-14
  • 打赏
  • 举报
回复
堆是由系统统一管理的,你要自己动态分配内存,要么弄明白系统分配原理,要么你自己另作一个堆管理体系
csdsjkk 2003-09-13
  • 打赏
  • 举报
回复
HANDLE HeapCreate(

DWORD flOptions, // heap allocation flag
DWORD dwInitialSize, // initial heap size
DWORD dwMaximumSize // maximum heap size
);

LPVOID HeapAlloc(

HANDLE hHeap, // handle to the private heap block
DWORD dwFlags, // heap allocation control flags
DWORD dwBytes // number of bytes to allocate
);
PlayerBox 2003-09-13
  • 打赏
  • 举报
回复
up
PlayerBox 2003-09-13
  • 打赏
  • 举报
回复
非常感谢您给我提供的资料.
但:
"我的目的是想知道如何用汇编实现动态分配内存的功能,"
PlayerBox 2003-09-13
  • 打赏
  • 举报
回复
楼上的大哥,这些我知道,
请看清楚我的问题好吗!!
gzshd 2003-09-13
  • 打赏
  • 举报
回复
6.4 逻辑与移位指令
逻辑指令会将标志寄存器中的OF和CF清零。
表6.3
not a a=~a(注意not与neg不同!)
and a, b a=a&b
or a, b a=a|b
xor a, b a=a^b

下面是移位指令,其中x可为8位立即数或CL寄存器。
表6.4
sal(也可写成shl) a, x 将a左移x位,CF=移出的那一位数空位用0补足
sar a, x 将有符号a右移x位,CF=移出的那一位数空位按a的符号用0/1补足
shr a, x 将无符号a右移x位,CF=移出的那一位数空位用0补足
rol a, x 将a循环左移(左边出去的数又从最右边回来)
ror a, x 将a循环右移(右边出去的数又从最左边回来)
rcl / rcr a, x 把CF放在目标最左边然后循环左/右移
shld a, b, x 将a左移x位, 空出位用b高端m位填充例:shld edx, eax, 16可将eax的高16位 放入dx中。
shrd a, b, x 将a右移x位, 空出位用b低端m位填充

6.5 比较、测试、转移与循环指令
比较与测试指令基本上总是与转移指令相配合使用,其形式分别为CMP a, b和TEST a, b。CMP实际上是根据a-b的值改变标志寄存器但不改变a和b,可以检测两个数的大小关系。TEST则是根据a&b的值改变标志寄存器,同样不改变a和b。这条指令可以用来测试a中哪些位为1。执行完这些指令后,立刻用转移指令就可实现条件转移,因为条件转移语句会根据标志寄存器决定是否转移。转移指令的使用方法就像这样:
__asm{
_addax: add ax,1; //_addax是标号
jmp _addax;
}
转移指令有:
JMP 无条件转移
JE / JZ ZF=1时转移
JNE / JNZ ZF=0时转移

JS SF=1时转移
JNS SF=0时转移
JO OF=1时转移
JNO OF=0时转移
JP / JPE PF=1时转移
JNP / JPO PF=0时转移

根据两无符号数关系转移:
JA / JNBE 大于时转移 (CF或ZF=0)
JBE / JNA 不大于时转移 (CF或ZF=1)
JB / JNAE / JC 小于时转移 (CF=1)
JNB / JAE / JNC 不小于时转移 (CF=0)

根据两有符号数关系转移:
JNLE / JG 大于时转移 ((SF异或OF)或ZF)=0 )
JLE / JNG 不大于时转移 ((SF异或OF)或ZF)=1 )
JL / JNGE 小于时转移 (SF异或OF=1)
JNL / JGE 不小于时转移 (SF异或OF=0)

特殊转移语句:
JECXZ CX=0时转移

为了记住这么多条指令,你只需知道一点,就是无符号数之间的关系分别被称为Above,Equal,Below,分别代表大于,等于,小于;有符号数之间相应的关系则分别被称为Great,Equal,Less。
事实上,有些转移是可以避免的。举个例子,要算一个数的绝对值是否要用转移呢?请看一段程序:
MOV EDX,EAX
SAR EDX,31 //EDX现在全为EAX的符号位
XOR EAX,EDX
SUB EAX,EDX

找出两个数中较大的一个应该要用转移吧?不过也可以象下面的解决方案那样利用标志,真是绝了:
SUB EBX,EAX
SBB ECX,ECX //如果EBX≥EAX,现在ECX=0,否则ECX=FFFFFFFF
AND ECX,EBX
ADD EAX,ECX

下面的一段程序实现了if (a != 0) a = b; else a = c;
CMP EAX,1
SBB EAX,EAX
XOR ECX,EBX
AND EAX,ECX
XOR EAX,EBX

循环语句常用的是LOOP,它等价于DEC CX加上JNZ。

下面看一个汇编的综合运用:冒泡排序。
#include <iostream>
using namespace std;

#define array_size 10

int a[array_size]={42, 73, 65, 97, 23, 59, 18, 84, 36, 6};

void main()
{
int *p;
p=&a[0];
p--;

__asm
{
mov esi,p;
mov ecx,array_size;
_outloop:
mov edx,ecx;
_inloop:
mov eax, [ esi+ecx*4 ]; //一个int占4字节
mov ebx, [ esi+edx*4 ];
cmp eax, ebx;
jnb _noxchg; //不交换
mov [ esi+ecx*4 ], ebx;
mov [ esi+edx*4 ], eax;
_noxchg:
dec edx;
jnz _inloop;
loop _outloop;
}

for (int i=0;i<10;i++)
cout<<a[i]<<" ";
}
加载更多回复(2)

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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