如何把汇编程序嵌入到C语言中

时间:2022-11-19 01:17:12
# include<stdio.h>
void main()
{
__asm
{
DATA SEGMENT
STRING1 DB 0DH,0AH,'Please input the first numbers:',0DH,0AH,'$'
STRING2 DB 0DH,0AH,'Please input the  second numbers:',0DH,0AH,'$'
NUM1 DW 0
NUM2 DW 0
DATA ENDS
CODE SEGMENT
  ASSUME CS:CODE,DS:DATA
START:MOV AX,DATA
      MOV DS,AX

      LEA DX,STRING1 ;9号功能,显示字符串1输入第一个数
      MOV AH,09H
      INT 21H
     
LP:
    MOV AH,1
    INT 21H
    CMP AL,0DH  ;当输入的字符为回车结束数据输入
    JZ NEXT
    SUB AL,30H
    MOV AH,0
    MOV CX,AX
    MOV BX,10
    MOV AX,NUM1
    MUL BX
    ADD AX,CX
    MOV NUM1,AX
    JMP LP
                   NEXT:   
                  
LEA DX,STRING2  ;9号功能,显示字符串2输入第二个数
      MOV AH,09H
      INT 21H
      
LP1:
    MOV AH,1
    INT 21H
    CMP AL,0DH
    JZ NEXT1  ;;当输入的字符为回车结束数据输入
    SUB AL,30H
    MOV AH,0
    MOV CX,AX
    MOV BX,10
    MOV AX,NUM2
    MUL BX
    ADD AX,CX
    MOV NUM2,AX
    JMP LP1
   NEXT1:

    CALL DOO    ;调用换行子程序
    CALL A      ;调用加法子程序
    CALL DOO   
    CALL B      ;调用减法子程序
    CALL DOO
    CALL C      ;调用乘法子程序
    CALL DOO 
    CALL D      ;调用换行子程序
    MOV AH,4CH  ;返回DOS
    INT 21H

A PROC NEAR      ;加法子程序
     MOV DX,NUM1  
     CALL PRINT  ;调用数据以十进制输出子程序,把NUM1以十进制形式输出
     MOV DL,'+'
     CALL STDOUT ;调用输出子程序,把+号输出
     MOV DX,NUM2
     CALL PRINT
     MOV DL,'='  ;调用输出子程序,把=号输出
     CALL STDOUT
     MOV AX,NUM1
     ADD AX,NUM2
     MOV DX,AX
     CALL PRINT
  RET
A ENDP
B PROC NEAR     ;减法子程序
     MOV DX,NUM1 
     CALL PRINT
     MOV DL,'-'
     CALL STDOUT
     MOV DX,NUM2
     CALL PRINT
     MOV DL,'='
     CALL STDOUT
     MOV AX,NUM1
     MOV BX,NUM2
     SUB AX,BX
     MOV DX,AX
     CALL PRINT
     RET
B  ENDP
C  PROC NEAR    ;乘法子程序
     MOV DX,NUM1 
     CALL PRINT
     MOV DL,'*'
     CALL STDOUT
     MOV DX,NUM2
     CALL PRINT
     MOV DL,'='
     CALL STDOUT
     MOV AX,NUM1
     MOV DX,0
     MUL NUM2
     MOV DX,AX
     CALL PRINT
    RET
C ENDP
D PROC NEAR     ;除法子程序
     MOV DX,NUM1 
     CALL PRINT
     MOV DL,'/'
     CALL STDOUT
     MOV DX,NUM2
     CALL PRINT
     MOV DL,'='
     CALL STDOUT
     MOV DX,0
     MOV AX,NUM1
     DIV NUM2
     MOV DX,AX
     CALL PRINT
     RET
D ENDP
PRINT PROC NEAR  ;数据以十进制输出子程序
    PUSH DX
    PUSH AX
    PUSH CX
    PUSH BX
    MOV CX,0
DO:MOV AX,DX
    MOV DX,0
    MOV BX,10
    DIV BX
    XCHG AX,DX
    ADD AL,30H
    PUSH AX
    INC CX
    CMP DX,0
    JNZ DO
DO1:POP AX
    MOV DL,AL
    CALL STDOUT  
    LOOP DO1
    POP BX
    POP CX
    POP AX
    POP DX
    RET
PRINT ENDP
STDOUT PROC NEAR  ;输出子程序
     MOV AH,2
     INT 21H
     RET
STDOUT ENDP

DOO PROC NEAR     ;换行子程序
    MOV AH,02H
    MOV DL,0DH
    INT 21H
    MOV AH,02H
    MOV DL,0AH
    INT 21H
    RET
DOO ENDP 
CODE ENDS
      END START
}
}




如上面的程序,编译的时候会报错。


1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(6): error C2400: “操作码”中的内联汇编语法错误;找到“SEGMENT”
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(7): error C2400: “操作码”中的内联汇编语法错误;找到“DB”
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(7): error C2015: 常量中的字符太多
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(8): error C2400: “操作码”中的内联汇编语法错误;找到“DB”
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(8): error C2015: 常量中的字符太多
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(9): error C2400: “操作码”中的内联汇编语法错误;找到“DW”
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(10): error C2400: “操作码”中的内联汇编语法错误;找到“DW”
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(11): error C2400: “操作码”中的内联汇编语法错误;找到“ENDS”
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(12): error C2400: “操作码”中的内联汇编语法错误;找到“SEGMENT”
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(13): warning C4405: “CS”: 标识符是保留字
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(13): error C2400: “操作码”中的内联汇编语法错误;找到“CS”
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(14): error C2443: 操作数大小冲突
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(30): error C2443: 操作数大小冲突
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(33): error C2443: 操作数大小冲突
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(50): error C2443: 操作数大小冲突
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(53): error C2443: 操作数大小冲突
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(68): error C2400: “操作码”中的内联汇编语法错误;找到“PROC”
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(69): error C2443: 操作数大小冲突
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(73): error C2443: 操作数大小冲突
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(77): error C2443: 操作数大小冲突
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(78): error C2443: 操作数大小冲突
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(82): error C2400: “操作码”中的内联汇编语法错误;找到“ENDP”
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(83): error C2400: “操作码”中的内联汇编语法错误;找到“PROC”
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(84): error C2443: 操作数大小冲突
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(88): error C2443: 操作数大小冲突
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(92): error C2443: 操作数大小冲突
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(93): error C2443: 操作数大小冲突
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(98): error C2400: “操作码”中的内联汇编语法错误;找到“ENDP”
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(99): error C2400: “操作码”中的内联汇编语法错误;找到“PROC”
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(100): error C2443: 操作数大小冲突
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(104): error C2443: 操作数大小冲突
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(108): error C2443: 操作数大小冲突
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(114): error C2400: “操作码”中的内联汇编语法错误;找到“ENDP”
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(115): error C2400: “操作码”中的内联汇编语法错误;找到“PROC”
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(116): error C2443: 操作数大小冲突
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(120): error C2443: 操作数大小冲突
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(125): error C2443: 操作数大小冲突
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(130): error C2400: “操作码”中的内联汇编语法错误;找到“ENDP”
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(131): error C2400: “操作码”中的内联汇编语法错误;找到“PROC”
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(156): error C2400: “操作码”中的内联汇编语法错误;找到“ENDP”
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(157): error C2400: “操作码”中的内联汇编语法错误;找到“PROC”
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(161): error C2400: “操作码”中的内联汇编语法错误;找到“ENDP”
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(163): error C2400: “操作码”中的内联汇编语法错误;找到“PROC”
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(171): error C2400: “操作码”中的内联汇编语法错误;找到“ENDP”
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(172): error C2400: “操作码”中的内联汇编语法错误;找到“ENDS”
1>d:\documents\visual studio 2010\projects\调试1\调试1\调试1.cpp(173): error C2400: “操作码”中的内联汇编语法错误;找到“START”



谁知道该如何嵌套。

43 个解决方案

#1


作为一个新手,别人的程序都不会用。真悲哀啊。

#2


这种代码,别嵌入了,直接汇编就可以了
VC++ 内部有汇编器,可以直接用
如果嫌麻烦,可以到网上下载
masm32 //32BitsWindows,以及16Bits Dos 汇编器
masm615 //masm 6.15 版本。

#3


引用 2 楼 lm_whales 的回复:
这种代码,别嵌入了,直接汇编就可以了
VC++ 内部有汇编器,可以直接用
如果嫌麻烦,可以到网上下载
masm32 //32BitsWindows,以及16Bits Dos 汇编器
masm615 //masm 6.15 版本。
请问VC++内部的汇编器怎么调用。没用过。

#4


直接在控制台 命令行输入 ml a.asm 就可以了
ml /? 可以得到帮助信息

#5


在BC31下嵌入16位汇编
在VC下嵌入32位汇编

#7


以下内容摘自bc++3.1 asm联机帮助:
  asm, _asm, __asm (keywords)
You use the asm statements to place assembly language statements in the
middle of your C++ source code.

 Syntax:
   asm <opcode> <operands> <; or newline>
   _asm <opcode> <operands> <; or newline>
   __asm <opcode> <operands> <; or newline>

Any C++ symbols are replaced by the appropriate assembly language
equivalents.

If you want to include a number of asm statements, surround them with
braces:

  asm {
pop ax; pop ds
iret
  }

 Example

  asm mov ax,_stklen

 See Also:
  BASM

#8


没见过把完整的汇编语言源程序嵌进去的

#9


不是所有汇编指令都支持

#10


之前我根本不知道c语言的程序里面能嵌入汇编,那天老师说可以,我才知道。具体如何嵌入让我自己去搜

#11


主观能动性还是要发挥的。

#12


内联汇编仅限汇编指令
那些汇编器定义的宏, 像 SEGMENT, DB, DW 之类的是不支持的. 可以用 _emit 指令可以代替 db 之类的宏.
在内联汇编里面可以直接访问 C/C++ 里面的变量和函数, 很多时候还是比独立汇编方便.

#13


仅供参考:
#pragma option -N-
//-------------------------------------------------------
#include <conio.h>
#include <dos.h>
#include <stdio.h>
//-------------------------------------------------------
#define YES         1
#define NO          0
#define CURSOR_MOVE 1
#define LEFT_DOWN   2
#define LEFT_UP     4
#define RIGHT_DOWN  8
#define RIGHT_UP    16
int MouseActive=NO,MouseMask,MouseButton,MouseX,MouseY;
//-------------------------------------------------------
void far mscall()
{
asm {
push ds
push si
xor si,si
mov ds,si
mov si,[0x40E]
mov ds,si
cmp ax,MouseMask
jne changed
cmp bx,MouseButton
jne changed
cmp cx,MouseX
jne changed
cmp dx,MouseY
je nochange
}
changed:
asm {
mov MouseMask,ax
mov MouseButton,bx
mov MouseX,cx
mov MouseY,dx
mov MouseActive,YES
jmp end
}
nochange:
asm {
mov MouseActive,NO
}
end:
asm {
pop si
pop ds
}
}
//-------------------------------------------------------
void MsLinkUserCall()
{
union REGS r;
struct SREGS sr;

*((int *)(0x0000040E))=FP_SEG(&MouseActive);
r.x.ax=0x0C;
r.x.cx=0x001F;
r.x.dx=FP_OFF(mscall);
sr.es=FP_SEG(mscall);
int86x(0x33,&r,&r,&sr);
}
//-------------------------------------------------------
int MsInstall()
{
void far *address;
union REGS regs;

address=getvect(0x33);
if((address==NULL)||(*(unsigned char *)address==0xCF)) return 0;
else {
regs.x.ax=0;
int86(0x33,&regs,&regs);
return regs.x.ax;
}
}
//-------------------------------------------------------
void MsShow()
{
union REGS regs;

regs.x.ax=1;
int86(0x33,&regs,&regs);
}
//-------------------------------------------------------
void MsHide()
{
union REGS regs;

regs.x.ax=2;
int86(0x33,&regs,&regs);
}
//-------------------------------------------------------
void MsSetLoc(x,y)
unsigned int x,y;
{
union REGS regs;

regs.x.ax=4;
regs.x.cx=x;
regs.x.dx=y;
int86(0x33,&regs,&regs);
}
//-------------------------------------------------------
void MsSetHoriLimit(l,r)
unsigned int l,r;
{
union REGS regs;

regs.x.ax=7;
regs.x.cx=l;
regs.x.dx=r;
int86(0x33,&regs,&regs);
}
//-------------------------------------------------------
void MsSetVertLimit(t,b)
unsigned int t,b;
{
union REGS regs;

regs.x.ax=8;
regs.x.cx=t;
regs.x.dx=b;
int86(0x33,&regs,&regs);
}
//-------------------------------------------------------
void main()
{
if (!MsInstall()) {
printf("I need a mouse.\n");
return;
}
clrscr();
MsLinkUserCall();
MsSetHoriLimit(0,638);
MsSetVertLimit(0,192);
MsSetLoc(0,0);
MsShow();
while (1) {
if (kbhit()) {
if (getch()==27) break;
}
if (MouseActive==YES) {
if (MouseMask&LEFT_DOWN) {
MsHide();printf(" LEFT_DOWN");MsShow();
}
if (MouseMask&LEFT_UP) {
MsHide();printf(" LEFT_UP");MsShow();
}
if (MouseMask&RIGHT_DOWN) {
MsHide();printf(" RIGHT_DOWN");MsShow();
}
if (MouseMask&RIGHT_UP) {
MsHide();printf(" RIGHT_UP");MsShow();
}
if (MouseButton&1) {
MsHide();printf(" LEFT_DRAG");MsShow();
}
if (MouseButton&2) {
MsHide();printf(" RIGHT_DRAG");MsShow();
}
if (MouseMask&CURSOR_MOVE) {
MsHide();printf(" MOVE_TO(%3d,%3d)",MouseX,MouseY);MsShow();
}
MsHide();printf("\n");MsShow();
MouseActive=NO;
}
}
MsHide();
MsInstall();
}

#14


VC++早就不支持生成16位程序,不论dos16、win16,你嵌入的是dos 16位汇编,根本不可能通过,而且还有一部分MASM语法在嵌入汇编中不支持。

#15


引用 13 楼 zhao4zhong1 的回复:
仅供参考:
#pragma option -N-
//-------------------------------------------------------
#include <conio.h>
#include <dos.h>
#include <stdio.h>
//-------------------------------------------------------
#define YES         1
#define NO          0
#define CURSOR_MOVE 1
#define LEFT_DOWN   2
#define LEFT_UP     4
#define RIGHT_DOWN  8
#define RIGHT_UP    16
int MouseActive=NO,MouseMask,MouseButton,MouseX,MouseY;
//-------------------------------------------------------
void far mscall()
{
asm {
push ds
push si
xor si,si
mov ds,si
mov si,[0x40E]
mov ds,si
cmp ax,MouseMask
jne changed
cmp bx,MouseButton
jne changed
cmp cx,MouseX
jne changed
cmp dx,MouseY
je nochange
}
changed:
asm {
mov MouseMask,ax
mov MouseButton,bx
mov MouseX,cx
mov MouseY,dx
mov MouseActive,YES
jmp end
}
nochange:
asm {
mov MouseActive,NO
}
end:
asm {
pop si
pop ds
}
}
//-------------------------------------------------------
void MsLinkUserCall()
{
union REGS r;
struct SREGS sr;

*((int *)(0x0000040E))=FP_SEG(&MouseActive);
r.x.ax=0x0C;
r.x.cx=0x001F;
r.x.dx=FP_OFF(mscall);
sr.es=FP_SEG(mscall);
int86x(0x33,&r,&r,&sr);
}
//-------------------------------------------------------
int MsInstall()
{
void far *address;
union REGS regs;

address=getvect(0x33);
if((address==NULL)||(*(unsigned char *)address==0xCF)) return 0;
else {
regs.x.ax=0;
int86(0x33,&regs,&regs);
return regs.x.ax;
}
}
//-------------------------------------------------------
void MsShow()
{
union REGS regs;

regs.x.ax=1;
int86(0x33,&regs,&regs);
}
//-------------------------------------------------------
void MsHide()
{
union REGS regs;

regs.x.ax=2;
int86(0x33,&regs,&regs);
}
//-------------------------------------------------------
void MsSetLoc(x,y)
unsigned int x,y;
{
union REGS regs;

regs.x.ax=4;
regs.x.cx=x;
regs.x.dx=y;
int86(0x33,&regs,&regs);
}
//-------------------------------------------------------
void MsSetHoriLimit(l,r)
unsigned int l,r;
{
union REGS regs;

regs.x.ax=7;
regs.x.cx=l;
regs.x.dx=r;
int86(0x33,&regs,&regs);
}
//-------------------------------------------------------
void MsSetVertLimit(t,b)
unsigned int t,b;
{
union REGS regs;

regs.x.ax=8;
regs.x.cx=t;
regs.x.dx=b;
int86(0x33,&regs,&regs);
}
//-------------------------------------------------------
void main()
{
if (!MsInstall()) {
printf("I need a mouse.\n");
return;
}
clrscr();
MsLinkUserCall();
MsSetHoriLimit(0,638);
MsSetVertLimit(0,192);
MsSetLoc(0,0);
MsShow();
while (1) {
if (kbhit()) {
if (getch()==27) break;
}
if (MouseActive==YES) {
if (MouseMask&LEFT_DOWN) {
MsHide();printf(" LEFT_DOWN");MsShow();
}
if (MouseMask&LEFT_UP) {
MsHide();printf(" LEFT_UP");MsShow();
}
if (MouseMask&RIGHT_DOWN) {
MsHide();printf(" RIGHT_DOWN");MsShow();
}
if (MouseMask&RIGHT_UP) {
MsHide();printf(" RIGHT_UP");MsShow();
}
if (MouseButton&1) {
MsHide();printf(" LEFT_DRAG");MsShow();
}
if (MouseButton&2) {
MsHide();printf(" RIGHT_DRAG");MsShow();
}
if (MouseMask&CURSOR_MOVE) {
MsHide();printf(" MOVE_TO(%3d,%3d)",MouseX,MouseY);MsShow();
}
MsHide();printf("\n");MsShow();
MouseActive=NO;
}
}
MsHide();
MsInstall();
}
赵老师,你这个程序太有用了。之前我看了一堆如何嵌入的,总是晕头转向,正在用“alt+8”来盗取汇编源代码呢,突然看见这个程序,原来如此啊。看来在开学之前完成任务的可能性进一步增强了。谢谢你,赵老师。

#16


D:\BC\flc>dir mouse*.c
 驱动器 D 中的卷是 Q_HD2_8
 卷的序列号是 54FC-A4FD

 D:\BC\flc 的目录

1998-03-31  14:55             3,428 MOUSETST.C
               1 个文件          3,428 字节
               0 个目录 16,783,536,128 可用字节

D:\BC\flc>
如何把汇编程序嵌入到C语言中

#17


提醒:
Win7下需要在DosBox中运行BC++3.1或TC

WinXP下,建一个批处理bc.bat,内容为下面两行,放在bc.exe同目录下,再将bc.bat发送到桌面快捷方式:
del tc*.swp >NUL
start command /c bc.exe
如果想在IDE里面使用鼠标,还应将快捷方式属性中的快速编辑模式关掉。

#18


引用 17 楼 zhao4zhong1 的回复:
提醒:
Win7下需要在DosBox中运行BC++3.1或TC

WinXP下,建一个批处理bc.bat,内容为下面两行,放在bc.exe同目录下,再将bc.bat发送到桌面快捷方式:
del tc*.swp >NUL
start command /c bc.exe
如果想在IDE里面使用鼠标,还应将快捷方式属性中的快速编辑模式关掉。
啊,赵老师,你说的我不太懂。嗯,首先你这个程序我只是看了他的结构,如何在C语言中整段的定义使用汇编语言的。对于程序的内容我没有细看,刚才你一说与鼠标相关的话题,我没听懂。你这个程序是讲如何在BC下使用鼠标吗?可是我记得BC下本来就可以使用鼠标啊。 如何把汇编程序嵌入到C语言中

#19


引用 18 楼 chimenghuanzhe 的回复:
Quote: 引用 17 楼 zhao4zhong1 的回复:

提醒:
Win7下需要在DosBox中运行BC++3.1或TC

WinXP下,建一个批处理bc.bat,内容为下面两行,放在bc.exe同目录下,再将bc.bat发送到桌面快捷方式:
del tc*.swp >NUL
start command /c bc.exe
如果想在IDE里面使用鼠标,还应将快捷方式属性中的快速编辑模式关掉。
啊,赵老师,你说的我不太懂。嗯,首先你这个程序我只是看了他的结构,如何在C语言中整段的定义使用汇编语言的。对于程序的内容我没有细看,刚才你一说与鼠标相关的话题,我没听懂。你这个程序是讲如何在BC下使用鼠标吗?可是我记得BC下本来就可以使用鼠标啊。 如何把汇编程序嵌入到C语言中

我是担心你在比如Win7下或Win7 64位下用不了BC

#20


引用 19 楼 zhao4zhong1 的回复:
Quote: 引用 18 楼 chimenghuanzhe 的回复:

Quote: 引用 17 楼 zhao4zhong1 的回复:

提醒:
Win7下需要在DosBox中运行BC++3.1或TC

WinXP下,建一个批处理bc.bat,内容为下面两行,放在bc.exe同目录下,再将bc.bat发送到桌面快捷方式:
del tc*.swp >NUL
start command /c bc.exe
如果想在IDE里面使用鼠标,还应将快捷方式属性中的快速编辑模式关掉。
啊,赵老师,你说的我不太懂。嗯,首先你这个程序我只是看了他的结构,如何在C语言中整段的定义使用汇编语言的。对于程序的内容我没有细看,刚才你一说与鼠标相关的话题,我没听懂。你这个程序是讲如何在BC下使用鼠标吗?可是我记得BC下本来就可以使用鼠标啊。 如何把汇编程序嵌入到C语言中

我是担心你在比如Win7下或Win7 64位下用不了BC


引用 19 楼 zhao4zhong1 的回复:
Quote: 引用 18 楼 chimenghuanzhe 的回复:

Quote: 引用 17 楼 zhao4zhong1 的回复:

提醒:
Win7下需要在DosBox中运行BC++3.1或TC

WinXP下,建一个批处理bc.bat,内容为下面两行,放在bc.exe同目录下,再将bc.bat发送到桌面快捷方式:
del tc*.swp >NUL
start command /c bc.exe
如果想在IDE里面使用鼠标,还应将快捷方式属性中的快速编辑模式关掉。
啊,赵老师,你说的我不太懂。嗯,首先你这个程序我只是看了他的结构,如何在C语言中整段的定义使用汇编语言的。对于程序的内容我没有细看,刚才你一说与鼠标相关的话题,我没听懂。你这个程序是讲如何在BC下使用鼠标吗?可是我记得BC下本来就可以使用鼠标啊。 如何把汇编程序嵌入到C语言中

我是担心你在比如Win7下或Win7 64位下用不了BC
我用的是VS2010啊,VC++6.0在win7下面无法使用,所以安装了VS2010,(因为没有找到单独的VC2010),虽然很不熟悉。至于汇编语言,我只是准备编几个子函数,加减乘除,每个子函数把参数传递进去,然后用汇编计算,然后再把结果传出来。这样,函数的主体部分还是用C编写的,不过,里面涉及到cos函数,我看它的源代码,是按照泰勒公式展开的,一直展开到了x的14次方,我的天哪,我这个x本身就有100位,最少也是64个字节,即64位(我是用unsigned char型数组),然后它再14次方,要多少位,有可能会冲到1400位,然后,Oh,my god!我相信的电脑会崩溃的。

#21


VS2010只能嵌入32位汇编,嵌入不了16位或64位汇编。
32位汇编参考下面:
X86和X87汇编指令大全(有注释)
---------- 一、数据传输指令 ----------------------------------------------------
它们在存贮器和寄存器、寄存器和输入输出端口之间传送数据.
1. 通用数据传送指令.
MOV 传送字或字节.
MOVSX 先符号扩展,再传送.
MOVZX 先零扩展,再传送.
PUSH 把字压入堆栈.
POP 把字弹出堆栈.
PUSHA 把AX,CX,DX,BX,SP,BP,SI,DI依次压入堆栈.
POPA 把DI,SI,BP,SP,BX,DX,CX,AX依次弹出堆栈.
PUSHAD 把EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI依次压入堆栈.
POPAD 把EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX依次弹出堆栈.
BSWAP 交换32位寄存器里字节的顺序
XCHG 交换字或字节.(至少有一个操作数为寄存器,段寄存器不可作为操作数)
CMPXCHG 比较并交换操作数.(第二个操作数必须为累加器AL/AX/EAX)
XADD 先交换再累加.(结果在第一个操作数里)
XLAT 字节查表转换.----BX指向一张256字节的表的起点,AL为表的索引值(0-255,即0-FFH);返回AL为查表结果.([BX+AL]->AL)
2. 输入输出端口传送指令.
IN I/O端口输入. ( 语法: IN 累加器, {端口号│DX} )
OUT I/O端口输出. ( 语法: OUT {端口号│DX},累加器 )输入输出端口由立即方式指定时, 其范围是 0-255; 由寄存器 DX 指定时,其范围是 0-65535.
3. 目的地址传送指令.
LEA 装入有效地址.例: LEA DX,string ;把偏移地址存到DX.
LDS 传送目标指针,把指针内容装入DS.例: LDS SI,string ;把段地址:偏移地址存到DS:SI.
LES 传送目标指针,把指针内容装入ES.例: LES DI,string ;把段地址:偏移地址存到ES:DI.
LFS 传送目标指针,把指针内容装入FS.例: LFS DI,string ;把段地址:偏移地址存到FS:DI.
LGS 传送目标指针,把指针内容装入GS.例: LGS DI,string ;把段地址:偏移地址存到GS:DI.
LSS 传送目标指针,把指针内容装入SS.例: LSS DI,string ;把段地址:偏移地址存到SS:DI.
4. 标志传送指令.
LAHF 标志寄存器传送,把标志装入AH.
SAHF 标志寄存器传送,把AH内容装入标志寄存器.
PUSHF 标志入栈.
POPF 标志出栈.
PUSHD 32位标志入栈.
POPD 32位标志出栈.
---------- 二、算术运算指令 ----------------------------------------------------
ADD 加法.
ADC 带进位加法.
INC 加 1.
AAA 加法的ASCII码调整.
DAA 加法的十进制调整.
SUB 减法.
SBB 带借位减法.
DEC 减 1.
NEG 求反(以 0 减之).
CMP 比较.(两操作数作减法,仅修改标志位,不回送结果).
AAS 减法的ASCII码调整.
DAS 减法的十进制调整.
MUL 无符号乘法.结果回送AH和AL(字节运算),或DX和AX(字运算),
IMUL 整数乘法.结果回送AH和AL(字节运算),或DX和AX(字运算),
AAM 乘法的ASCII码调整.
DIV 无符号除法.结果回送:商回送AL,余数回送AH, (字节运算);或 商回送AX,余数回送DX, (字运算).
IDIV 整数除法.结果回送:商回送AL,余数回送AH, (字节运算);或 商回送AX,余数回送DX, (字运算).
AAD 除法的ASCII码调整.
CBW 字节转换为字. (把AL中字节的符号扩展到AH中去)
CWD 字转换为双字. (把AX中的字的符号扩展到DX中去)
CWDE 字转换为双字. (把AX中的字符号扩展到EAX中去)
CDQ 双字扩展. (把EAX中的字的符号扩展到EDX中去)
---------- 三、逻辑运算指令 ----------------------------------------------------
AND 与运算.
OR 或运算.
XOR 异或运算.
NOT 取反.
TEST 测试.(两操作数作与运算,仅修改标志位,不回送结果).
SHL 逻辑左移.
SAL 算术左移.(=SHL)
SHR 逻辑右移.
SAR 算术右移.(=SHR)
ROL 循环左移.
ROR 循环右移.
RCL 通过进位的循环左移.
RCR 通过进位的循环右移.
  以上八种移位指令,其移位次数可达255次.
  移位一次时, 可直接用操作码. 如 SHL AX,1.
  移位>1次时, 则由寄存器CL给出移位次数.
  如 MOV CL,04 SHL AX,CL
---------- 四、串指令 ----------------------------------------------------------
  DS:SI 源串段寄存器 :源串变址.
  ES:DI 目标串段寄存器:目标串变址.
  CX 重复次数计数器.
  AL/AX 扫描值.
  D标志 0表示重复操作中SI和DI应自动增量; 1表示应自动减量.
  Z标志 用来控制扫描或比较操作的结束.
MOVS 串传送.( MOVSB 传送字符. MOVSW 传送字. MOVSD 传送双字. )
CMPS 串比较.( CMPSB 比较字符. CMPSW 比较字. )
SCAS 串扫描.把AL或AX的内容与目标串作比较,比较结果反映在标志位.
LODS 装入串.把源串中的元素(字或字节)逐一装入AL或AX中.( LODSB 传送字符. LODSW 传送字. LODSD 传送双字. )
STOS 保存串.是LODS的逆过程.
REP 当CX/ECX<>0时重复.
REPE/REPZ 当ZF=1或比较结果相等,且CX/ECX<>0时重复.
REPNE/REPNZ 当ZF=0或比较结果不相等,且CX/ECX<>0时重复.
REPC 当CF=1且CX/ECX<>0时重复.
REPNC 当CF=0且CX/ECX<>0时重复.
---------- 五、程序转移指令 ----------------------------------------------------
1. 无条件转移指令 (长转移)
JMP 无条件转移指令
CALL 过程调用
RET/RETF 过程返回.
2. 条件转移指令 (短转移,-128到+127的距离内)( 当且仅当(SF XOR OF)=1时,OP1<OP2 )
JA/JNBE 不小于或不等于时转移.
JAE/JNB 大于或等于转移.
JB/JNAE 小于转移.
JBE/JNA 小于或等于转移.
以上四条,测试无符号整数运算的结果(标志C和Z).
JG/JNLE 大于转移.
JGE/JNL 大于或等于转移.
JL/JNGE 小于转移.
JLE/JNG 小于或等于转移.
以上四条,测试带符号整数运算的结果(标志S,O和Z).
JE/JZ 等于转移.
JNE/JNZ 不等于时转移.
JC 有进位时转移.
JNC 无进位时转移.
JNO 不溢出时转移.
JNP/JPO 奇偶性为奇数时转移.
JNS 符号位为 "0" 时转移.
JO 溢出转移.
JP/JPE 奇偶性为偶数时转移.
JS 符号位为 "1" 时转移.
3. 循环控制指令(短转移)
LOOP CX不为零时循环.
LOOPE/LOOPZ CX不为零且标志Z=1时循环.
LOOPNE/LOOPNZ CX不为零且标志Z=0时循环.
JCXZ CX为零时转移.
JECXZ ECX为零时转移.
4. 中断指令
INT 中断指令
INTO 溢出中断
IRET 中断返回
5. 处理器控制指令
HLT 处理器暂停, 直到出现中断或复位信号才继续.
WAIT 当芯片引线TEST为高电平时使CPU进入等待状态.
ESC 转换到外处理器.
LOCK *总线.
NOP 空操作.
STC 置进位标志位.
CLC 清进位标志位.
CMC 进位标志取反.
STD 置方向标志位.
CLD 清方向标志位.
STI 置中断允许位.
CLI 清中断允许位.
---------- 六、伪指令 ----------------------------------------------------------
DW 定义字(2字节).
PROC 定义过程.
ENDP 过程结束.
SEGMENT 定义段.
ASSUME 建立段寄存器寻址.
ENDS 段结束.
END 程序结束.
---------- 七、处理机控制指令:标志处理指令 ------------------------------------
CLC 进位位置0指令
CMC 进位位求反指令
STC 进位位置为1指令
CLD 方向标志置1指令
STD 方向标志位置1指令
CLI 中断标志置0指令
STI 中断标志置1指令
NOP 无操作
HLT 停机
WAIT 等待
ESC 换码
LOCK *
========== 浮点运算指令集 ======================================================
---------- 一、控制指令(带9B的控制指令前缀F变为FN时浮点不检查,机器码去掉9B)----
FINIT   初始化浮点部件    机器码  9B DB E3
FCLEX   清除异常    机器码  9B DB E2
FDISI   浮点检查禁止中断    机器码  9B DB E1
FENI   浮点检查禁止中断二    机器码  9B DB E0
WAIT   同步CPU和FPU    机器码  9B
FWAIT   同步CPU和FPU    机器码  D9 D0
FNOP   无操作    机器码  DA E9
FXCH   交换ST(0)和ST(1)    机器码  D9 C9
FXCH ST(i)   交换ST(0)和ST(i)    机器码  D9 C1iii
FSTSW ax   状态字到ax    机器码  9B DF E0
FSTSW word ptr mem  状态字到mem    机器码  9B DD mm111mmm
FLDCW word ptr mem  mem到状态字    机器码  D9 mm101mmm
FSTCW word ptr mem  控制字到mem    机器码  9B D9 mm111mmm

FLDENV word ptr mem  mem到全环境    机器码  D9 mm100mmm
FSTENV word ptr mem  全环境到mem    机器码  9B D9 mm110mmm
FRSTOR word ptr mem  mem到FPU状态    机器码  DD mm100mmm
FSAVE word ptr mem  FPU状态到mem    机器码  9B DD mm110mmm

FFREE ST(i)   标志ST(i)未使用    机器码  DD C0iii
FDECSTP   减少栈指针1->0 2->1    机器码  D9 F6
FINCSTP   增加栈指针0->1 1->2    机器码  D9 F7
FSETPM   浮点设置保护    机器码  DB E4
---------- 二、数据传送指令 ----------------------------------------------------
FLDZ   将0.0装入ST(0)    机器码  D9 EE
FLD1   将1.0装入ST(0)    机器码  D9 E8
FLDPI   将π装入ST(0)    机器码  D9 EB
FLDL2T   将ln10/ln2装入ST(0)    机器码  D9 E9
FLDL2E   将1/ln2装入ST(0)    机器码  D9 EA
FLDLG2   将ln2/ln10装入ST(0)    机器码  D9 EC
FLDLN2   将ln2装入ST(0)    机器码  D9 ED

FLD    real4 ptr mem  装入mem的单精度浮点数    机器码  D9 mm000mmm
FLD    real8 ptr mem  装入mem的双精度浮点数    机器码  DD mm000mmm
FLD   real10 ptr mem  装入mem的十字节浮点数    机器码  DB mm101mmm

FILD word ptr mem  装入mem的二字节整数    机器码  DF mm000mmm
FILD   dword ptr mem  装入mem的四字节整数    机器码  DB mm000mmm
FILD   qword ptr mem  装入mem的八字节整数    机器码  DF mm101mmm

FBLD   tbyte ptr mem  装入mem的十字节BCD数    机器码  DF mm100mmm

FST    real4 ptr mem  保存单精度浮点数到mem    机器码  D9 mm010mmm
FST    real8 ptr mem  保存双精度浮点数到mem    机器码  DD mm010mmm

FIST word ptr mem  保存二字节整数到mem    机器码  DF mm010mmm
FIST   dword ptr mem  保存四字节整数到mem    机器码  DB mm010mmm

FSTP   real4 ptr mem  保存单精度浮点数到mem并出栈    机器码  D9 mm011mmm
FSTP   real8 ptr mem  保存双精度浮点数到mem并出栈    机器码  DD mm011mmm
FSTP  real10 ptr mem  保存十字节浮点数到mem并出栈    机器码  DB mm111mmm

FISTP word ptr mem  保存二字节整数到mem并出栈    机器码  DF mm011mmm
FISTP  dword ptr mem  保存四字节整数到mem并出栈    机器码  DB mm011mmm
FISTP  qword ptr mem  保存八字节整数到mem并出栈    机器码  DF mm111mmm

FBSTP  tbyte ptr mem  保存十字节BCD数到mem并出栈    机器码  DF mm110mmm

FCMOVB   ST(0),ST(i) <时传送    机器码  DA C0iii
FCMOVBE   ST(0),ST(i) <=时传送    机器码  DA D0iii
FCMOVE   ST(0),ST(i) =时传送    机器码  DA C1iii
FCMOVNB   ST(0),ST(i) >=时传送    机器码  DB C0iii
FCMOVNBE   ST(0),ST(i) >时传送    机器码  DB D0iii
FCMOVNE   ST(0),ST(i) !=时传送    机器码  DB C1iii
FCMOVNU   ST(0),ST(i) 有序时传送    机器码  DB D1iii
FCMOVU   ST(0),ST(i) 无序时传送    机器码  DA D1iii
---------- 三、比较指令 --------------------------------------------------------
FCOM   ST(0)-ST(1)    机器码  D8 D1
FCOMI   ST(0),ST(i)  ST(0)-ST(1)    机器码  DB F0iii
FCOMIP   ST(0),ST(i)  ST(0)-ST(1)并出栈   机器码  DF F0iii
FCOM   real4 ptr mem  ST(0)-实数mem    机器码  D8 mm010mmm
FCOM   real8 ptr mem  ST(0)-实数mem    机器码  DC mm010mmm

FICOM word ptr mem  ST(0)-整数mem    机器码  DE mm010mmm
FICOM  dword ptr mem  ST(0)-整数mem    机器码  DA mm010mmm
FICOMP word ptr mem  ST(0)-整数mem并出栈    机器码  DE mm011mmm
FICOMP dword ptr mem  ST(0)-整数mem并出栈    机器码  DA mm011mmm

FTST   ST(0)-0    机器码  D9 E4
FUCOM  ST(i)   ST(0)-ST(i)    机器码  DD E0iii
FUCOMP ST(i)   ST(0)-ST(i)并出栈    机器码  DD E1iii
FUCOMPP   ST(0)-ST(1)并二次出栈    机器码  DA E9
FXAM   ST(0)规格类型    机器码  D9 E5
---------- 四、运算指令 --------------------------------------------------------
FADD   把目的操作数 (直接接在指令后的变量或堆栈缓存器) 与来源操作数 (接在目的操作数后的变量或堆栈缓存器) 相加,并将结果存入目的操作数
FADDP  ST(i),ST   这个指令是使目的操作数加上 ST 缓存器,并弹出 ST 缓存器,而目的操作数必须是堆栈缓存器的其中之一,最后不管目的操作数为何,经弹出一次后,目的操作数会变成上一个堆栈缓存器了
FIADD   FIADD 是把 ST 加上来源操作数,然后再存入 ST 缓存器,来源操作数必须是字组整数或短整数形态的变数

FSUB   减
FSUBP
FSUBR   减数与被减数互换
FSUBRP
FISUB
FISUBR

FMUL   乘
FMULP
FIMUL

FDIV   除
FDIVP
FDIVR
FDIVRP
FIDIV
FIDIVR

FCHS   改变 ST 的正负值

FABS   把 ST 之值取出,取其绝对值后再存回去。

FSQRT   将 ST 之值取出,开根号后再存回去。

FSCALE   这个指令是计算 ST*2^ST(1)之值,再把结果存入 ST 里而 ST(1) 之值不变。ST(1) 必须是在 -32768 到 32768 (-215 到 215 )之间的整数,如果超过这个范围计算结果无法确定,如果不是整数 ST(1) 会先向零舍入成整数再计算。所以为安全起见,最好是由字组整数载入到 ST(1) 里。

FRNDINT   这个指令是把 ST 的数值舍入成整数,FPU 提供四种舍入方式,由 FPU 的控制字组(control word)中的 RC 两个位决定
  RC 舍入控制
  00 四舍五入
  01 向负无限大舍入
  10 向正无限大舍入
  11 向零舍去
================================================================================

#22


引用 21 楼 zhao4zhong1 的回复:
VS2010只能嵌入32位汇编,嵌入不了16位或64位汇编。
32位汇编参考下面:
X86和X87汇编指令大全(有注释)
---------- 一、数据传输指令 ----------------------------------------------------
它们在存贮器和寄存器、寄存器和输入输出端口之间传送数据.
1. 通用数据传送指令.
MOV 传送字或字节.
MOVSX 先符号扩展,再传送.
MOVZX 先零扩展,再传送.
PUSH 把字压入堆栈.
POP 把字弹出堆栈.
PUSHA 把AX,CX,DX,BX,SP,BP,SI,DI依次压入堆栈.
POPA 把DI,SI,BP,SP,BX,DX,CX,AX依次弹出堆栈.
PUSHAD 把EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI依次压入堆栈.
POPAD 把EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX依次弹出堆栈.
BSWAP 交换32位寄存器里字节的顺序
XCHG 交换字或字节.(至少有一个操作数为寄存器,段寄存器不可作为操作数)
CMPXCHG 比较并交换操作数.(第二个操作数必须为累加器AL/AX/EAX)
XADD 先交换再累加.(结果在第一个操作数里)
XLAT 字节查表转换.----BX指向一张256字节的表的起点,AL为表的索引值(0-255,即0-FFH);返回AL为查表结果.([BX+AL]->AL)
2. 输入输出端口传送指令.
IN I/O端口输入. ( 语法: IN 累加器, {端口号│DX} )
OUT I/O端口输出. ( 语法: OUT {端口号│DX},累加器 )输入输出端口由立即方式指定时, 其范围是 0-255; 由寄存器 DX 指定时,其范围是 0-65535.
3. 目的地址传送指令.
LEA 装入有效地址.例: LEA DX,string ;把偏移地址存到DX.
LDS 传送目标指针,把指针内容装入DS.例: LDS SI,string ;把段地址:偏移地址存到DS:SI.
LES 传送目标指针,把指针内容装入ES.例: LES DI,string ;把段地址:偏移地址存到ES:DI.
LFS 传送目标指针,把指针内容装入FS.例: LFS DI,string ;把段地址:偏移地址存到FS:DI.
LGS 传送目标指针,把指针内容装入GS.例: LGS DI,string ;把段地址:偏移地址存到GS:DI.
LSS 传送目标指针,把指针内容装入SS.例: LSS DI,string ;把段地址:偏移地址存到SS:DI.
4. 标志传送指令.
LAHF 标志寄存器传送,把标志装入AH.
SAHF 标志寄存器传送,把AH内容装入标志寄存器.
PUSHF 标志入栈.
POPF 标志出栈.
PUSHD 32位标志入栈.
POPD 32位标志出栈.
---------- 二、算术运算指令 ----------------------------------------------------
ADD 加法.
ADC 带进位加法.
INC 加 1.
AAA 加法的ASCII码调整.
DAA 加法的十进制调整.
SUB 减法.
SBB 带借位减法.
DEC 减 1.
NEG 求反(以 0 减之).
CMP 比较.(两操作数作减法,仅修改标志位,不回送结果).
AAS 减法的ASCII码调整.
DAS 减法的十进制调整.
MUL 无符号乘法.结果回送AH和AL(字节运算),或DX和AX(字运算),
IMUL 整数乘法.结果回送AH和AL(字节运算),或DX和AX(字运算),
AAM 乘法的ASCII码调整.
DIV 无符号除法.结果回送:商回送AL,余数回送AH, (字节运算);或 商回送AX,余数回送DX, (字运算).
IDIV 整数除法.结果回送:商回送AL,余数回送AH, (字节运算);或 商回送AX,余数回送DX, (字运算).
AAD 除法的ASCII码调整.
CBW 字节转换为字. (把AL中字节的符号扩展到AH中去)
CWD 字转换为双字. (把AX中的字的符号扩展到DX中去)
CWDE 字转换为双字. (把AX中的字符号扩展到EAX中去)
CDQ 双字扩展. (把EAX中的字的符号扩展到EDX中去)
---------- 三、逻辑运算指令 ----------------------------------------------------
AND 与运算.
OR 或运算.
XOR 异或运算.
NOT 取反.
TEST 测试.(两操作数作与运算,仅修改标志位,不回送结果).
SHL 逻辑左移.
SAL 算术左移.(=SHL)
SHR 逻辑右移.
SAR 算术右移.(=SHR)
ROL 循环左移.
ROR 循环右移.
RCL 通过进位的循环左移.
RCR 通过进位的循环右移.
  以上八种移位指令,其移位次数可达255次.
  移位一次时, 可直接用操作码. 如 SHL AX,1.
  移位>1次时, 则由寄存器CL给出移位次数.
  如 MOV CL,04 SHL AX,CL
---------- 四、串指令 ----------------------------------------------------------
  DS:SI 源串段寄存器 :源串变址.
  ES:DI 目标串段寄存器:目标串变址.
  CX 重复次数计数器.
  AL/AX 扫描值.
  D标志 0表示重复操作中SI和DI应自动增量; 1表示应自动减量.
  Z标志 用来控制扫描或比较操作的结束.
MOVS 串传送.( MOVSB 传送字符. MOVSW 传送字. MOVSD 传送双字. )
CMPS 串比较.( CMPSB 比较字符. CMPSW 比较字. )
SCAS 串扫描.把AL或AX的内容与目标串作比较,比较结果反映在标志位.
LODS 装入串.把源串中的元素(字或字节)逐一装入AL或AX中.( LODSB 传送字符. LODSW 传送字. LODSD 传送双字. )
STOS 保存串.是LODS的逆过程.
REP 当CX/ECX<>0时重复.
REPE/REPZ 当ZF=1或比较结果相等,且CX/ECX<>0时重复.
REPNE/REPNZ 当ZF=0或比较结果不相等,且CX/ECX<>0时重复.
REPC 当CF=1且CX/ECX<>0时重复.
REPNC 当CF=0且CX/ECX<>0时重复.
---------- 五、程序转移指令 ----------------------------------------------------
1. 无条件转移指令 (长转移)
JMP 无条件转移指令
CALL 过程调用
RET/RETF 过程返回.
2. 条件转移指令 (短转移,-128到+127的距离内)( 当且仅当(SF XOR OF)=1时,OP1<OP2 )
JA/JNBE 不小于或不等于时转移.
JAE/JNB 大于或等于转移.
JB/JNAE 小于转移.
JBE/JNA 小于或等于转移.
以上四条,测试无符号整数运算的结果(标志C和Z).
JG/JNLE 大于转移.
JGE/JNL 大于或等于转移.
JL/JNGE 小于转移.
JLE/JNG 小于或等于转移.
以上四条,测试带符号整数运算的结果(标志S,O和Z).
JE/JZ 等于转移.
JNE/JNZ 不等于时转移.
JC 有进位时转移.
JNC 无进位时转移.
JNO 不溢出时转移.
JNP/JPO 奇偶性为奇数时转移.
JNS 符号位为 "0" 时转移.
JO 溢出转移.
JP/JPE 奇偶性为偶数时转移.
JS 符号位为 "1" 时转移.
3. 循环控制指令(短转移)
LOOP CX不为零时循环.
LOOPE/LOOPZ CX不为零且标志Z=1时循环.
LOOPNE/LOOPNZ CX不为零且标志Z=0时循环.
JCXZ CX为零时转移.
JECXZ ECX为零时转移.
4. 中断指令
INT 中断指令
INTO 溢出中断
IRET 中断返回
5. 处理器控制指令
HLT 处理器暂停, 直到出现中断或复位信号才继续.
WAIT 当芯片引线TEST为高电平时使CPU进入等待状态.
ESC 转换到外处理器.
LOCK *总线.
NOP 空操作.
STC 置进位标志位.
CLC 清进位标志位.
CMC 进位标志取反.
STD 置方向标志位.
CLD 清方向标志位.
STI 置中断允许位.
CLI 清中断允许位.
---------- 六、伪指令 ----------------------------------------------------------
DW 定义字(2字节).
PROC 定义过程.
ENDP 过程结束.
SEGMENT 定义段.
ASSUME 建立段寄存器寻址.
ENDS 段结束.
END 程序结束.
---------- 七、处理机控制指令:标志处理指令 ------------------------------------
CLC 进位位置0指令
CMC 进位位求反指令
STC 进位位置为1指令
CLD 方向标志置1指令
STD 方向标志位置1指令
CLI 中断标志置0指令
STI 中断标志置1指令
NOP 无操作
HLT 停机
WAIT 等待
ESC 换码
LOCK *
========== 浮点运算指令集 ======================================================
---------- 一、控制指令(带9B的控制指令前缀F变为FN时浮点不检查,机器码去掉9B)----
FINIT   初始化浮点部件    机器码  9B DB E3
FCLEX   清除异常    机器码  9B DB E2
FDISI   浮点检查禁止中断    机器码  9B DB E1
FENI   浮点检查禁止中断二    机器码  9B DB E0
WAIT   同步CPU和FPU    机器码  9B
FWAIT   同步CPU和FPU    机器码  D9 D0
FNOP   无操作    机器码  DA E9
FXCH   交换ST(0)和ST(1)    机器码  D9 C9
FXCH ST(i)   交换ST(0)和ST(i)    机器码  D9 C1iii
FSTSW ax   状态字到ax    机器码  9B DF E0
FSTSW word ptr mem  状态字到mem    机器码  9B DD mm111mmm
FLDCW word ptr mem  mem到状态字    机器码  D9 mm101mmm
FSTCW word ptr mem  控制字到mem    机器码  9B D9 mm111mmm

FLDENV word ptr mem  mem到全环境    机器码  D9 mm100mmm
FSTENV word ptr mem  全环境到mem    机器码  9B D9 mm110mmm
FRSTOR word ptr mem  mem到FPU状态    机器码  DD mm100mmm
FSAVE word ptr mem  FPU状态到mem    机器码  9B DD mm110mmm

FFREE ST(i)   标志ST(i)未使用    机器码  DD C0iii
FDECSTP   减少栈指针1->0 2->1    机器码  D9 F6
FINCSTP   增加栈指针0->1 1->2    机器码  D9 F7
FSETPM   浮点设置保护    机器码  DB E4
---------- 二、数据传送指令 ----------------------------------------------------
FLDZ   将0.0装入ST(0)    机器码  D9 EE
FLD1   将1.0装入ST(0)    机器码  D9 E8
FLDPI   将π装入ST(0)    机器码  D9 EB
FLDL2T   将ln10/ln2装入ST(0)    机器码  D9 E9
FLDL2E   将1/ln2装入ST(0)    机器码  D9 EA
FLDLG2   将ln2/ln10装入ST(0)    机器码  D9 EC
FLDLN2   将ln2装入ST(0)    机器码  D9 ED

FLD    real4 ptr mem  装入mem的单精度浮点数    机器码  D9 mm000mmm
FLD    real8 ptr mem  装入mem的双精度浮点数    机器码  DD mm000mmm
FLD   real10 ptr mem  装入mem的十字节浮点数    机器码  DB mm101mmm

FILD word ptr mem  装入mem的二字节整数    机器码  DF mm000mmm
FILD   dword ptr mem  装入mem的四字节整数    机器码  DB mm000mmm
FILD   qword ptr mem  装入mem的八字节整数    机器码  DF mm101mmm

FBLD   tbyte ptr mem  装入mem的十字节BCD数    机器码  DF mm100mmm

FST    real4 ptr mem  保存单精度浮点数到mem    机器码  D9 mm010mmm
FST    real8 ptr mem  保存双精度浮点数到mem    机器码  DD mm010mmm

FIST word ptr mem  保存二字节整数到mem    机器码  DF mm010mmm
FIST   dword ptr mem  保存四字节整数到mem    机器码  DB mm010mmm

FSTP   real4 ptr mem  保存单精度浮点数到mem并出栈    机器码  D9 mm011mmm
FSTP   real8 ptr mem  保存双精度浮点数到mem并出栈    机器码  DD mm011mmm
FSTP  real10 ptr mem  保存十字节浮点数到mem并出栈    机器码  DB mm111mmm

FISTP word ptr mem  保存二字节整数到mem并出栈    机器码  DF mm011mmm
FISTP  dword ptr mem  保存四字节整数到mem并出栈    机器码  DB mm011mmm
FISTP  qword ptr mem  保存八字节整数到mem并出栈    机器码  DF mm111mmm

FBSTP  tbyte ptr mem  保存十字节BCD数到mem并出栈    机器码  DF mm110mmm

FCMOVB   ST(0),ST(i) <时传送    机器码  DA C0iii
FCMOVBE   ST(0),ST(i) <=时传送    机器码  DA D0iii
FCMOVE   ST(0),ST(i) =时传送    机器码  DA C1iii
FCMOVNB   ST(0),ST(i) >=时传送    机器码  DB C0iii
FCMOVNBE   ST(0),ST(i) >时传送    机器码  DB D0iii
FCMOVNE   ST(0),ST(i) !=时传送    机器码  DB C1iii
FCMOVNU   ST(0),ST(i) 有序时传送    机器码  DB D1iii
FCMOVU   ST(0),ST(i) 无序时传送    机器码  DA D1iii
---------- 三、比较指令 --------------------------------------------------------
FCOM   ST(0)-ST(1)    机器码  D8 D1
FCOMI   ST(0),ST(i)  ST(0)-ST(1)    机器码  DB F0iii
FCOMIP   ST(0),ST(i)  ST(0)-ST(1)并出栈   机器码  DF F0iii
FCOM   real4 ptr mem  ST(0)-实数mem    机器码  D8 mm010mmm
FCOM   real8 ptr mem  ST(0)-实数mem    机器码  DC mm010mmm

FICOM word ptr mem  ST(0)-整数mem    机器码  DE mm010mmm
FICOM  dword ptr mem  ST(0)-整数mem    机器码  DA mm010mmm
FICOMP word ptr mem  ST(0)-整数mem并出栈    机器码  DE mm011mmm
FICOMP dword ptr mem  ST(0)-整数mem并出栈    机器码  DA mm011mmm

FTST   ST(0)-0    机器码  D9 E4
FUCOM  ST(i)   ST(0)-ST(i)    机器码  DD E0iii
FUCOMP ST(i)   ST(0)-ST(i)并出栈    机器码  DD E1iii
FUCOMPP   ST(0)-ST(1)并二次出栈    机器码  DA E9
FXAM   ST(0)规格类型    机器码  D9 E5
---------- 四、运算指令 --------------------------------------------------------
FADD   把目的操作数 (直接接在指令后的变量或堆栈缓存器) 与来源操作数 (接在目的操作数后的变量或堆栈缓存器) 相加,并将结果存入目的操作数
FADDP  ST(i),ST   这个指令是使目的操作数加上 ST 缓存器,并弹出 ST 缓存器,而目的操作数必须是堆栈缓存器的其中之一,最后不管目的操作数为何,经弹出一次后,目的操作数会变成上一个堆栈缓存器了
FIADD   FIADD 是把 ST 加上来源操作数,然后再存入 ST 缓存器,来源操作数必须是字组整数或短整数形态的变数

FSUB   减
FSUBP
FSUBR   减数与被减数互换
FSUBRP
FISUB
FISUBR

FMUL   乘
FMULP
FIMUL

FDIV   除
FDIVP
FDIVR
FDIVRP
FIDIV
FIDIVR

FCHS   改变 ST 的正负值

FABS   把 ST 之值取出,取其绝对值后再存回去。

FSQRT   将 ST 之值取出,开根号后再存回去。

FSCALE   这个指令是计算 ST*2^ST(1)之值,再把结果存入 ST 里而 ST(1) 之值不变。ST(1) 必须是在 -32768 到 32768 (-215 到 215 )之间的整数,如果超过这个范围计算结果无法确定,如果不是整数 ST(1) 会先向零舍入成整数再计算。所以为安全起见,最好是由字组整数载入到 ST(1) 里。

FRNDINT   这个指令是把 ST 的数值舍入成整数,FPU 提供四种舍入方式,由 FPU 的控制字组(control word)中的 RC 两个位决定
  RC 舍入控制
  00 四舍五入
  01 向负无限大舍入
  10 向正无限大舍入
  11 向零舍去
================================================================================
感觉这个指令表比我的书上的都全。当然,之前你说的那个直接翻译成汇编语言那个,绝了。我差点忍不住直接粘上去。

#23


《The Intel 64 and IA-32 Architectures Software Developer's Manual》

#24


再供参考:
#include <stdio.h>
float data[500];
int i;
void main() {
    for (i=0;i<500;i++) {data[i]=1.0f;printf("%g\n",data[i]);}
    __asm {
        push ecx
        push edi
        mov ecx,500
        mov eax,0xBF800000 //-1.0f
        lea edi,data
        rep stosd
        pop edi
        pop ecx
    }
    for (i=0;i<500;i++) printf("%g\n",data[i]);
}

#25


引用 24 楼 zhao4zhong1 的回复:
再供参考:
#include <stdio.h>
float data[500];
int i;
void main() {
    for (i=0;i<500;i++) {data[i]=1.0f;printf("%g\n",data[i]);}
    __asm {
        push ecx
        push edi
        mov ecx,500
        mov eax,0xBF800000 //-1.0f
        lea edi,data
        rep stosd
        pop edi
        pop ecx
    }
    for (i=0;i<500;i++) printf("%g\n",data[i]);
}
赵老师,我想把两个数组,unsigned char a[10],b[8];把他们中的元素,按照a[1]+b[1]=c[1],a[2]+b[2]=c[2],这样计算,把结果放在数组unsigned char c[10]中(a[0]和b[0]不动),请问,用汇编实现这个程序的时候,需要进位的话,是判断OF=1还是判断CF=1,。备注:每个元素如a[i]能存储的数据是从0——255,也就是只有当它彻底存满以后才开始进位的,我想,此时只要判断进位标识符或者溢出标识符就可以了吧?可是,它既是进位又是溢出啊,或者说我对进位和溢出还是没有弄清楚,所以这个题应该是看OF还是CF?如果是减法或者乘法也一样吧?

#27


@赵4老师 
我先是把程序写成了C语言的形式,就是这一段,用来实现大整数相加的。然后在调试的时候,按“alt+8”,反汇编,然后把反汇编的代码粘贴到相应的位置。结果是,C语言产生的结果正确,而嵌入了汇编的程序,结果完全错误。嗯,应该说是从第三位开始出错。
一下是C语言代码,
#include <stdio.h>
#define MAXINT 20

int bigplus(unsigned char a[],unsigned char b[],unsigned char c[]);

int main(int argc, char *argv[])
{
  unsigned char a[MAXINT]={10,5,4,6,5,4,3,2,1,1,1};     //被乘数或被除数
  unsigned char b[MAXINT]={7,7,6,5,4,3,2,1};             //乘数或除数
  unsigned char c[MAXINT],d[MAXINT];                    //c[]存放商,d[]存放余数
  int div=1234;                               //小乘数或小除数
  int k=0;
  int *res=&k;                                //小余数整数指针
  bigplus(a,b,c);
 
  getchar();
  return 0;
}

int bigplus(unsigned char a[],unsigned char b[],unsigned char c[])  //大整数加法
{
    int i,len;
    len=(a[0]>b[0]?a[0]:b[0]);  //a[0] b[0]保存数组长度,len为较长的一个
    for(i=0;i<MAXINT;i++)       //将数组清0
        c[i]=0;
    for (i=1;i<=len;i++)        //计算每一位的值
    {
        c[i]+=(a[i]+b[i]);
        if (c[i]>=10)
        {
           c[i]-=10;            //大于10的取个位
           c[i+1]++;            //高位加1
        }
    }
    if (c[i+1]>0) len++;
        c[0]=len;                //c[0]保存结果数组实际长度
    printf("Big integers add: ");
    for (i=len;i>=1;i--)
                printf("%d",c[i]); //打印结果
        printf("\n");
    return 0;
}



然后是反汇编出来的。
 




,最后是我嵌入的,因为要涉及到跳转,反汇编出来的跳转位置我无法确定,只好把他们分割成不同的小段。

							     

#28


然后是反汇编出来的。
--- d:\documents\visual studio 2010\projects\调试5\调试5\调试5.cpp -------------------
     1: #include <stdio.h>
     2: #define MAXINT 20
     3: 
     4: int bigplus(unsigned char a[],unsigned char b[],unsigned char c[]);
     5: 
     6: int main(int argc, char *argv[])
     7: {
00DB13A0  push        ebp  
00DB13A1  mov         ebp,esp  
00DB13A3  sub         esp,158h  
00DB13A9  push        ebx  
00DB13AA  push        esi  
00DB13AB  push        edi  
00DB13AC  lea         edi,[ebp-158h]  
00DB13B2  mov         ecx,56h  
00DB13B7  mov         eax,0CCCCCCCCh  
00DB13BC  rep stos    dword ptr es:[edi]  
00DB13BE  mov         eax,dword ptr [___security_cookie (0DB7000h)]  
00DB13C3  xor         eax,ebp  
00DB13C5  mov         dword ptr [ebp-4],eax  
     8:   unsigned char a[MAXINT]={10,5,4,6,5,4,3,2,1,1,1};     //被乘数或被除数
00DB13C8  mov         byte ptr [ebp-1Ch],0Ah  
00DB13CC  mov         byte ptr [ebp-1Bh],5  
00DB13D0  mov         byte ptr [ebp-1Ah],4  
00DB13D4  mov         byte ptr [ebp-19h],6  
00DB13D8  mov         byte ptr [ebp-18h],5  
00DB13DC  mov         byte ptr [ebp-17h],4  
00DB13E0  mov         byte ptr [ebp-16h],3  
00DB13E4  mov         byte ptr [ebp-15h],2  
00DB13E8  mov         byte ptr [ebp-14h],1  
00DB13EC  mov         byte ptr [ebp-13h],1  
00DB13F0  mov         byte ptr [ebp-12h],1  
00DB13F4  xor         eax,eax  
00DB13F6  mov         dword ptr [ebp-11h],eax  
00DB13F9  mov         dword ptr [ebp-0Dh],eax  
00DB13FC  mov         byte ptr [ebp-9],al  
     9:   unsigned char b[MAXINT]={7,7,6,5,4,3,2,1};             //乘数或除数
00DB13FF  mov         byte ptr [ebp-38h],7  
00DB1403  mov         byte ptr [ebp-37h],7  
00DB1407  mov         byte ptr [ebp-36h],6  
00DB140B  mov         byte ptr [ebp-35h],5  
00DB140F  mov         byte ptr [ebp-34h],4  
00DB1413  mov         byte ptr [ebp-33h],3  
00DB1417  mov         byte ptr [ebp-32h],2  
00DB141B  mov         byte ptr [ebp-31h],1  
00DB141F  xor         eax,eax  
00DB1421  mov         dword ptr [ebp-30h],eax  
00DB1424  mov         dword ptr [ebp-2Ch],eax  
00DB1427  mov         dword ptr [ebp-28h],eax  
    10:   unsigned char c[MAXINT],d[MAXINT];                    //c[]存放商,d[]存放余数
    11:   int div=1234;                               //小乘数或小除数
00DB142A  mov         dword ptr [ebp-7Ch],4D2h  
    12:   int k=0;
00DB1431  mov         dword ptr [ebp-88h],0  
    13:   int *res=&k;                                //小余数整数指针
00DB143B  lea         eax,[ebp-88h]  
00DB1441  mov         dword ptr [ebp-94h],eax  
    14:   bigplus(a,b,c);
00DB1447  lea         eax,[ebp-54h]  
00DB144A  push        eax  
00DB144B  lea         ecx,[ebp-38h]  
00DB144E  push        ecx  
00DB144F  lea         edx,[ebp-1Ch]  
00DB1452  push        edx  
00DB1453  call        bigplus (0DB11B8h)  
00DB1458  add         esp,0Ch  
    15:  
    16:   getchar();
00DB145B  mov         esi,esp  
00DB145D  call        dword ptr [__imp__getchar (0DB82B8h)]  
00DB1463  cmp         esi,esp  
00DB1465  call        @ILT+295(__RTC_CheckEsp) (0DB112Ch)  
    17:   return 0;
00DB146A  xor         eax,eax  
    18: }
00DB146C  push        edx  
00DB146D  mov         ecx,ebp  
00DB146F  push        eax  
00DB1470  lea         edx,[ (0DB149Ch)]  
00DB1476  call        @ILT+120(@_RTC_CheckStackVars@8) (0DB107Dh)  
00DB147B  pop         eax  
00DB147C  pop         edx  
00DB147D  pop         edi  
00DB147E  pop         esi  
00DB147F  pop         ebx  
00DB1480  mov         ecx,dword ptr [ebp-4]  
00DB1483  xor         ecx,ebp  
00DB1485  call        @ILT+15(@__security_check_cookie@4) (0DB1014h)  
00DB148A  add         esp,158h  
00DB1490  cmp         ebp,esp  
00DB1492  call        @ILT+295(__RTC_CheckEsp) (0DB112Ch)  
00DB1497  mov         esp,ebp  
00DB1499  pop         ebp  
00DB149A  ret  
00DB149B  nop  
00DB149C  db          05h  
00DB149D  db          00h  
00DB149E  db          00h  
00DB149F  db          00h  
00DB14A0  db          a4h  
00DB14A1  db          14h  
00DB14A2  db          dbh  
00DB14A3  db          00h  
00DB14A4  db          e4h  
00DB14A5  db          ffh  
00DB14A6  db          ffh  
00DB14A7  db          ffh  
00DB14A8  db          14h  
00DB14A9  db          00h  
00DB14AA  db          00h  
00DB14AB  db          00h  
00DB14AC  db          e8h  
00DB14AD  db          14h  
00DB14AE  db          dbh  
00DB14AF  db          00h  
00DB14B0  db          c8h  
00DB14B1  db          ffh  
00DB14B2  db          ffh  
00DB14B3  db          ffh  
00DB14B4  db          14h  
00DB14B5  db          00h  
00DB14B6  db          00h  
00DB14B7  db          00h  
00DB14B8  db          e6h  
00DB14B9  db          14h  
00DB14BA  db          dbh  
00DB14BB  db          00h  
00DB14BC  db          ach  
00DB14BD  db          ffh  
00DB14BE  db          ffh  
00DB14BF  db          ffh  
00DB14C0  db          14h  
00DB14C1  db          00h  
00DB14C2  db          00h  
00DB14C3  db          00h  
00DB14C4  db          e4h  
00DB14C5  db          14h  
00DB14C6  db          dbh  
00DB14C7  db          00h  
00DB14C8  db          90h  
00DB14C9  db          ffh  
00DB14CA  db          ffh  
00DB14CB  db          ffh  
00DB14CC  db          14h  
00DB14CD  db          00h  
00DB14CE  db          00h  
00DB14CF  db          00h  
00DB14D0  db          e2h  
00DB14D1  db          14h  
00DB14D2  db          dbh  
00DB14D3  db          00h  
00DB14D4  db          78h  
00DB14D5  db          ffh  
00DB14D6  db          ffh  
00DB14D7  db          ffh  
00DB14D8  db          04h  
00DB14D9  db          00h  
00DB14DA  db          00h  
00DB14DB  db          00h  
00DB14DC  db          e0h  
00DB14DD  db          14h  
00DB14DE  db          dbh  
00DB14DF  db          00h  
00DB14E0  db          6bh  
00DB14E1  db          00h  
00DB14E2  db          64h  
00DB14E3  db          00h  
00DB14E4  db          63h  
00DB14E5  db          00h  
00DB14E6  db          62h  
00DB14E7  db          00h  
00DB14E8  db          61h  
00DB14E9  db          00h  
--- 无源文件 -----------------------------------------------------------------------
00DB14EA  int         3  
00DB14EB  int         3  
00DB14EC  int         3  
00DB14ED  int         3  
00DB14EE  int         3  
00DB14EF  int         3  
00DB14F0  int         3  
00DB14F1  int         3  
00DB14F2  int         3  
00DB14F3  int         3  
00DB14F4  int         3  
00DB14F5  int         3  
00DB14F6  int         3  
00DB14F7  int         3  
00DB14F8  int         3  
00DB14F9  int         3  
00DB14FA  int         3  
00DB14FB  int         3  
00DB14FC  int         3  
00DB14FD  int         3  
00DB14FE  int         3  
00DB14FF  int         3  
00DB1500  int         3  
00DB1501  int         3  
00DB1502  int         3  
00DB1503  int         3  
00DB1504  int         3  
00DB1505  int         3  
00DB1506  int         3  
00DB1507  int         3  
00DB1508  int         3  
00DB1509  int         3  
00DB150A  int         3  
00DB150B  int         3  
00DB150C  int         3  
00DB150D  int         3  
00DB150E  int         3  
00DB150F  int         3  
00DB1510  int         3  
00DB1511  int         3  
00DB1512  int         3  
00DB1513  int         3  
00DB1514  int         3  
00DB1515  int         3  
00DB1516  int         3  
00DB1517  int         3  
00DB1518  int         3  
00DB1519  int         3  
00DB151A  int         3  
00DB151B  int         3  
00DB151C  int         3  
00DB151D  int         3  
00DB151E  int         3  
00DB151F  int         3  
00DB1520  int         3  
00DB1521  int         3  
00DB1522  int         3  
00DB1523  int         3  
00DB1524  int         3  
00DB1525  int         3  
00DB1526  int         3  
00DB1527  int         3  
00DB1528  int         3  
00DB1529  int         3  
00DB152A  int         3  
00DB152B  int         3  
00DB152C  int         3  
00DB152D  int         3  
00DB152E  int         3  
00DB152F  int         3  
00DB1530  int         3  
00DB1531  int         3  
00DB1532  int         3  
00DB1533  int         3  
00DB1534  int         3  
00DB1535  int         3  
00DB1536  int         3  
00DB1537  int         3  
00DB1538  int         3  
00DB1539  int         3  
00DB153A  int         3  
00DB153B  int         3  
00DB153C  int         3  
00DB153D  int         3  
00DB153E  int         3  
00DB153F  int         3  

 

#29


接着

--- d:\documents\visual studio 2010\projects\调试5\调试5\调试5.cpp -------------------
    19: 
    20: int bigplus(unsigned char a[],unsigned char b[],unsigned char c[])  //大整数加法
    21: {
00DB1540  push        ebp  
00DB1541  mov         ebp,esp  
00DB1543  sub         esp,0DCh  
00DB1549  push        ebx  
00DB154A  push        esi  
00DB154B  push        edi  
00DB154C  lea         edi,[ebp-0DCh]  
00DB1552  mov         ecx,37h  
00DB1557  mov         eax,0CCCCCCCCh  
00DB155C  rep stos    dword ptr es:[edi]  
    22:     int i,len;
    23:     len=(a[0]>b[0]?a[0]:b[0]);  //a[0] b[0]保存数组长度,len为较长的一个
00DB155E  mov         eax,dword ptr [a]  
00DB1561  movzx       ecx,byte ptr [eax]  
00DB1564  mov         edx,dword ptr [b]  
00DB1567  movzx       eax,byte ptr [edx]  
00DB156A  cmp         ecx,eax  
00DB156C  jle         bigplus+3Bh (0DB157Bh)  
00DB156E  mov         ecx,dword ptr [a]  
00DB1571  mov         dl,byte ptr [ecx]  
00DB1573  mov         byte ptr [ebp-0D9h],dl  
00DB1579  jmp         bigplus+46h (0DB1586h)  
00DB157B  mov         eax,dword ptr [b]  
00DB157E  mov         cl,byte ptr [eax]  
00DB1580  mov         byte ptr [ebp-0D9h],cl  
00DB1586  movzx       edx,byte ptr [ebp-0D9h]  
00DB158D  mov         dword ptr [len],edx  
    24:     for(i=0;i<MAXINT;i++)       //将数组清0
00DB1590  mov         dword ptr [i],0  
00DB1597  jmp         bigplus+62h (0DB15A2h)  
00DB1599  mov         eax,dword ptr [i]  
00DB159C  add         eax,1  
00DB159F  mov         dword ptr [i],eax  
00DB15A2  cmp         dword ptr [i],14h  
00DB15A6  jge         bigplus+73h (0DB15B3h)  
    25:         c[i]=0;
00DB15A8  mov         eax,dword ptr [c]  
00DB15AB  add         eax,dword ptr [i]  
00DB15AE  mov         byte ptr [eax],0  
00DB15B1  jmp         bigplus+59h (0DB1599h)  
    26:     for (i=1;i<=len;i++)        //计算每一位的值
00DB15B3  mov         dword ptr [i],1  
00DB15BA  jmp         bigplus+85h (0DB15C5h)  
00DB15BC  mov         eax,dword ptr [i]  
00DB15BF  add         eax,1  
00DB15C2  mov         dword ptr [i],eax  
00DB15C5  mov         eax,dword ptr [i]  
00DB15C8  cmp         eax,dword ptr [len]  
00DB15CB  jg          bigplus+0EDh (0DB162Dh)  
    27:     {
    28:         c[i]+=(a[i]+b[i]);
00DB15CD  mov         eax,dword ptr [a]  
00DB15D0  add         eax,dword ptr [i]  
00DB15D3  movzx       ecx,byte ptr [eax]  
00DB15D6  mov         edx,dword ptr [b]  
00DB15D9  add         edx,dword ptr [i]  
00DB15DC  movzx       eax,byte ptr [edx]  
00DB15DF  add         ecx,eax  
00DB15E1  mov         edx,dword ptr [c]  
00DB15E4  add         edx,dword ptr [i]  
00DB15E7  movzx       eax,byte ptr [edx]  
00DB15EA  add         eax,ecx  
00DB15EC  mov         ecx,dword ptr [c]  
00DB15EF  add         ecx,dword ptr [i]  
00DB15F2  mov         byte ptr [ecx],al  
    29:         if (c[i]>=10)
00DB15F4  mov         eax,dword ptr [c]  
00DB15F7  add         eax,dword ptr [i]  
00DB15FA  movzx       ecx,byte ptr [eax]  
00DB15FD  cmp         ecx,0Ah  
00DB1600  jl          bigplus+0EBh (0DB162Bh)  
    30:         {
    31:            c[i]-=10;            //大于10的取个位
00DB1602  mov         eax,dword ptr [c]  
00DB1605  add         eax,dword ptr [i]  
00DB1608  movzx       ecx,byte ptr [eax]  
00DB160B  sub         ecx,0Ah  
00DB160E  mov         edx,dword ptr [c]  
00DB1611  add         edx,dword ptr [i]  
00DB1614  mov         byte ptr [edx],cl  
    32:            c[i+1]++;            //高位加1
00DB1616  mov         eax,dword ptr [c]  
00DB1619  add         eax,dword ptr [i]  
00DB161C  mov         cl,byte ptr [eax+1]  
00DB161F  add         cl,1  
00DB1622  mov         edx,dword ptr [c]  
00DB1625  add         edx,dword ptr [i]  
00DB1628  mov         byte ptr [edx+1],cl  
    33:         }
    34:     }
00DB162B  jmp         bigplus+7Ch (0DB15BCh)  
    35:     if (c[i+1]>0) len++;
00DB162D  mov         eax,dword ptr [c]  
00DB1630  add         eax,dword ptr [i]  
00DB1633  movzx       ecx,byte ptr [eax+1]  
00DB1637  test        ecx,ecx  
00DB1639  jle         bigplus+104h (0DB1644h)  
00DB163B  mov         eax,dword ptr [len]  
00DB163E  add         eax,1  
00DB1641  mov         dword ptr [len],eax  
    36:         c[0]=len;                //c[0]保存结果数组实际长度
00DB1644  mov         eax,dword ptr [c]  
00DB1647  mov         cl,byte ptr [len]  
00DB164A  mov         byte ptr [eax],cl  
    37:     printf("Big integers add: ");
00DB164C  mov         esi,esp  
00DB164E  push        offset string "Big integers add: " (0DB5744h)  
00DB1653  call        dword ptr [__imp__printf (0DB82B4h)]  
00DB1659  add         esp,4  
00DB165C  cmp         esi,esp  
00DB165E  call        @ILT+295(__RTC_CheckEsp) (0DB112Ch)  
    38:     for (i=len;i>=1;i--)
00DB1663  mov         eax,dword ptr [len]  
00DB1666  mov         dword ptr [i],eax  
00DB1669  jmp         bigplus+134h (0DB1674h)  
00DB166B  mov         eax,dword ptr [i]  
00DB166E  sub         eax,1  
00DB1671  mov         dword ptr [i],eax  
00DB1674  cmp         dword ptr [i],1  
00DB1678  jl          bigplus+15Dh (0DB169Dh)  
    39:                 printf("%d",c[i]); //打印结果
00DB167A  mov         eax,dword ptr [c]  
00DB167D  add         eax,dword ptr [i]  
00DB1680  movzx       ecx,byte ptr [eax]  
00DB1683  mov         esi,esp  
00DB1685  push        ecx  
00DB1686  push        offset string "%d" (0DB5740h)  
00DB168B  call        dword ptr [__imp__printf (0DB82B4h)]  
00DB1691  add         esp,8  
00DB1694  cmp         esi,esp  
00DB1696  call        @ILT+295(__RTC_CheckEsp) (0DB112Ch)  
00DB169B  jmp         bigplus+12Bh (0DB166Bh)  
    40:         printf("\n");
00DB169D  mov         esi,esp  
00DB169F  push        offset string "\n" (0DB573Ch)  
00DB16A4  call        dword ptr [__imp__printf (0DB82B4h)]  
00DB16AA  add         esp,4  
00DB16AD  cmp         esi,esp  
00DB16AF  call        @ILT+295(__RTC_CheckEsp) (0DB112Ch)  
    41:     return 0;
00DB16B4  xor         eax,eax  
    42: }
00DB16B6  pop         edi  
00DB16B7  pop         esi  
00DB16B8  pop         ebx  
00DB16B9  add         esp,0DCh  
00DB16BF  cmp         ebp,esp  
00DB16C1  call        @ILT+295(__RTC_CheckEsp) (0DB112Ch)  
00DB16C6  mov         esp,ebp  
00DB16C8  pop         ebp  
00DB16C9  ret  

#30


代码功能归根结底不是别人帮自己看或讲解或注释出来的;而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。
提醒:再牛×的老师也无法代替学生自己领悟和上厕所!
单步调试和设断点调试(VS IDE中编译连接通过以后,按F10或F11键单步执行,按Shift+F11退出当前函数;在某行按F9设断点后按F5执行停在该断点处。)是程序员必须掌握的技能之一。

#31


最后是我嵌入C语言的代码。
#include<stdio.h>
# define MAXINT 20
int bigplus(unsigned char a[],unsigned char b[],unsigned char c[]);
int main(int argc, char *argv[])
{
unsigned char a[MAXINT]={10,0,9,8,7,6,5,4,3,2,1};
unsigned char b[MAXINT]={8,8,7,6,5,4,3,2,1};
unsigned char c[MAXINT],d[MAXINT];                    //c[]存放商,d[]存放余数,g[]是除法时每次相乘的结果

 bigplus(a,b,c);
 return 0;
}
 
int bigplus(unsigned char a[],unsigned char b[],unsigned char c[])
{
 int i,len;
    len=(a[0]>b[0]?a[0]:b[0]);  //a[0] b[0]保存数组长度,len为较长的一个
printf("len=%d\n",len);
for(i=0;i<MAXINT;i++)       //将数组清0
{  
c[i]=0;
}
__asm
{
mov         dword ptr [i],1  
jmp         dian
}

dian:
__asm
{
        mov         eax,dword ptr [i]  
cmp         eax,dword ptr [len]  
jg          dian2
//c[i]+=(a[i]+b[i]);
mov         eax,dword ptr [a]  
add         eax,dword ptr [i]  
movzx       ecx,byte ptr [eax]  
mov         edx,dword ptr [b]  
add         edx,dword ptr [i]  
movzx       eax,byte ptr [edx]  
add         ecx,eax  
mov         edx,dword ptr [c]  
add         edx,dword ptr [i]  
    movzx       eax,byte ptr [edx]  
add         eax,ecx  
mov         ecx,dword ptr [c]  
add         ecx,dword ptr [i]  
mov         byte ptr [ecx],al  
//       if (c[i]>=10)
    mov         eax,dword ptr [c]  
add         eax,dword ptr [i]  
movzx       ecx,byte ptr [eax]  
cmp         ecx,0Ah  
jl          dian3       //小于10,跳转到开始循环位置
   // c[i]-=10;            //大于10的取个位
mov         eax,dword ptr [c]  
add         eax,dword ptr [i]  
        movzx       ecx,byte ptr [eax]  
        sub         ecx,0Ah  
        mov         edx,dword ptr [c]  
        add         edx,dword ptr [i]  
        mov         byte ptr [edx],cl  
//        c[i+1]++;            //高位加1
mov         eax,dword ptr [c]  
        add         eax,dword ptr [i]  
        mov         cl,byte ptr [eax+1]  
        add         cl,1  
        mov         edx,dword ptr [c]  
        add         edx,dword ptr [i]  
        mov         byte ptr [edx+1],cl  
// jmp         bigplus+7Ch (13315BCh)  
}
dian3:
__asm
{
      mov         eax,dword ptr [i]  
add         eax,1  
mov         dword ptr [i],eax  
        mov         eax,dword ptr [i]  
cmp         eax,dword ptr [len]  
jg          dian2
//c[i]+=(a[i]+b[i]);
mov         eax,dword ptr [a]  
add         eax,dword ptr [i]  
movzx       ecx,byte ptr [eax]  
mov         edx,dword ptr [b]  
add         edx,dword ptr [i]  
movzx       eax,byte ptr [edx]  
add         ecx,eax  
mov         edx,dword ptr [c]  
add         edx,dword ptr [i]  
    movzx       eax,byte ptr [edx]  
add         eax,ecx  
mov         ecx,dword ptr [c]  
add         ecx,dword ptr [i]  
mov         byte ptr [ecx],al    
 //       if (c[i]>=10)
    mov         eax,dword ptr [c]  
add         eax,dword ptr [i]  
movzx       ecx,byte ptr [eax]  
cmp         ecx,0Ah  
jl          dian3
//  jl          bg  //小于10,跳转到开始循环位置
   // c[i]-=10;            //大于10的取个位
mov         eax,dword ptr [c]  
add         eax,dword ptr [i]  
        movzx       ecx,byte ptr [eax]  
        sub         ecx,0Ah  
        mov         edx,dword ptr [c]  
        add         edx,dword ptr [i]  
        mov         byte ptr [edx],cl  
   //        c[i+1]++;            //高位加1
mov         eax,dword ptr [c]  
        add         eax,dword ptr [i]  
        mov         cl,byte ptr [eax+1]  
        add         cl,1  
        mov         edx,dword ptr [c]  
        add         edx,dword ptr [i]  
        mov         byte ptr [edx+1],cl  
// jmp         bigplus+7Ch (13315BCh)  
}
dian2:
__asm
{
mov         eax,dword ptr [c]  
        add         eax,dword ptr [i]  
        movzx       ecx,byte ptr [eax+1]  
        test        ecx,ecx  
        jle         dian4
        mov         eax,dword ptr [len]  
        add         eax,1  
        mov         dword ptr [len],eax  
jmp        dian4
}
   //    c[0]=len;                //c[0]保存结果数组实际长度

dian4:  
__asm
{
mov         eax,dword ptr [c]  
        mov         cl,byte ptr [len]  
        mov         byte ptr [eax],cl  
}
printf("Big integers add: ");
// printf("10进制:");
    for (i=len;i>=1;i--)
{
                printf("%d,",c[i]); //打印结果

}
        printf("\n");
return 0;
}



因为原始的的反汇编代码,要跳转,而且跳转的位置还是直接用地址表示的。而我在编写的时候无法知道地址信息。所以一开始我是把相应的地址对应的行给标上一个名字,比如jmp     jisuan。然后我把某一行前面标上jisuan:,然而,运行的结果是,貌似电脑无法识别这种标识。当然了,我记得在编写纯粹的汇编语言代码时是可以的,但是也许在C语言中是无法识别的。当然,没有报错,只是结果不对。

然后我把对应的跳转程序,分成一个个的小段,从这段跳转到另一段。结果是,程序不报错,但是结果不对。只有个位和十位正确,从百位开始就错了。往后更是都变成了0。
如果您忙的话,不用仔细看程序,跟我说说我是不是引用的格式(或者方式)不对啊。

#32


试试:
项目、属性、配置属性、C/C++、输出文件、汇编程序输出:程序集、机器码和源代码(/Facs)
在重新编译,查看生成的.asm文件内容。
如何把汇编程序嵌入到C语言中

#33


再重新编译

#34


引用 30 楼 zhao4zhong1 的回复:
代码功能归根结底不是别人帮自己看或讲解或注释出来的;而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。
提醒:再牛×的老师也无法代替学生自己领悟和上厕所!
单步调试和设断点调试(VS IDE中编译连接通过以后,按F10或F11键单步执行,按Shift+F11退出当前函数;在某行按F9设断点后按F5执行停在该断点处。)是程序员必须掌握的技能之一。
我按F10或者F11,逐过程或者逐语句的调试,但是在main()函数里运行到子函数的时候,跳入子函数,然后再按往下走的时候,马上他就又进行反汇编了。紧接着就在不同的文件中调用,跳转,最后退出。总之没有在我的子函数中继续往下走。是不是说明我的子函数有逻辑上的问题啊。

#35


VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。

#36


哈哈哈哈,嵌入成功了。感谢赵老师@赵4老师 ,感谢楼上各位的帮助。谢谢大家!!!!

#37


引用 36 楼 chimenghuanzhe 的回复:
哈哈哈哈,嵌入成功了。感谢赵老师@赵4老师 ,感谢楼上各位的帮助。谢谢大家!!!!

如何把汇编程序嵌入到C语言中小确幸!

#38


引用 36 楼 chimenghuanzhe 的回复:
哈哈哈哈,嵌入成功了。感谢赵老师@赵4老师 ,感谢楼上各位的帮助。谢谢大家!!!!
虽说老师交给我的任务离完成还遥遥无期,但是毕竟是迈出了第一步。接下来我只要把C语言编好的加减乘除都转化成汇编语言,就已经完成了10%。然后再完成cos函数的运算,这就完成了60%。最后用龙格库塔算法把微分积分方程的数值解求出来就算完成了90%,最后把结果写入txt文件中就是真正的完成了。

一开始接手这个任务时,我信心满满,可是当自己着手开始做的时候,才发现,对于一个512位的数据,我怎么表示,这就成了第一大难关,如果不解决了,接下来的计算就无法进行。之后我试着位运算来计算加减乘除,可是,却不知道减法和乘法如何实现,更别提除法了。于是只好用C语言的算术运算来解决。被老师狠狠地批了一顿,并要求我必须用汇编或者位运算来完成计算过程。从此接近5天了,终于把汇编嵌入到了C语言中。虽然对开学之前完成整个工作抱有悲观看法,但是还是要继续努力做下去。总之要把它完成。

#39


老师也有老师对的地方和难处。 如何把汇编程序嵌入到C语言中

#40


引用 39 楼 zhao4zhong1 的回复:
老师也有老师对的地方和难处。 如何把汇编程序嵌入到C语言中
嗯哪嗯哪,我理解。

#41


恭喜,蹭点分

#42


引用 41 楼 Dobzhansky 的回复:
恭喜,蹭点分

欢迎欢迎 如何把汇编程序嵌入到C语言中

#43


你只是源码级别的嵌入,我们可以考虑目标文件级别的嵌入。即汇编代码用汇编程序编译成目标文件,C语言代码用C编译器编译成目标文件,然后利用连接器链接这两个目标文件。

#1


作为一个新手,别人的程序都不会用。真悲哀啊。

#2


这种代码,别嵌入了,直接汇编就可以了
VC++ 内部有汇编器,可以直接用
如果嫌麻烦,可以到网上下载
masm32 //32BitsWindows,以及16Bits Dos 汇编器
masm615 //masm 6.15 版本。

#3


引用 2 楼 lm_whales 的回复:
这种代码,别嵌入了,直接汇编就可以了
VC++ 内部有汇编器,可以直接用
如果嫌麻烦,可以到网上下载
masm32 //32BitsWindows,以及16Bits Dos 汇编器
masm615 //masm 6.15 版本。
请问VC++内部的汇编器怎么调用。没用过。

#4


直接在控制台 命令行输入 ml a.asm 就可以了
ml /? 可以得到帮助信息

#5


在BC31下嵌入16位汇编
在VC下嵌入32位汇编

#6


#7


以下内容摘自bc++3.1 asm联机帮助:
  asm, _asm, __asm (keywords)
You use the asm statements to place assembly language statements in the
middle of your C++ source code.

 Syntax:
   asm <opcode> <operands> <; or newline>
   _asm <opcode> <operands> <; or newline>
   __asm <opcode> <operands> <; or newline>

Any C++ symbols are replaced by the appropriate assembly language
equivalents.

If you want to include a number of asm statements, surround them with
braces:

  asm {
pop ax; pop ds
iret
  }

 Example

  asm mov ax,_stklen

 See Also:
  BASM

#8


没见过把完整的汇编语言源程序嵌进去的

#9


不是所有汇编指令都支持

#10


之前我根本不知道c语言的程序里面能嵌入汇编,那天老师说可以,我才知道。具体如何嵌入让我自己去搜

#11


主观能动性还是要发挥的。

#12


内联汇编仅限汇编指令
那些汇编器定义的宏, 像 SEGMENT, DB, DW 之类的是不支持的. 可以用 _emit 指令可以代替 db 之类的宏.
在内联汇编里面可以直接访问 C/C++ 里面的变量和函数, 很多时候还是比独立汇编方便.

#13


仅供参考:
#pragma option -N-
//-------------------------------------------------------
#include <conio.h>
#include <dos.h>
#include <stdio.h>
//-------------------------------------------------------
#define YES         1
#define NO          0
#define CURSOR_MOVE 1
#define LEFT_DOWN   2
#define LEFT_UP     4
#define RIGHT_DOWN  8
#define RIGHT_UP    16
int MouseActive=NO,MouseMask,MouseButton,MouseX,MouseY;
//-------------------------------------------------------
void far mscall()
{
asm {
push ds
push si
xor si,si
mov ds,si
mov si,[0x40E]
mov ds,si
cmp ax,MouseMask
jne changed
cmp bx,MouseButton
jne changed
cmp cx,MouseX
jne changed
cmp dx,MouseY
je nochange
}
changed:
asm {
mov MouseMask,ax
mov MouseButton,bx
mov MouseX,cx
mov MouseY,dx
mov MouseActive,YES
jmp end
}
nochange:
asm {
mov MouseActive,NO
}
end:
asm {
pop si
pop ds
}
}
//-------------------------------------------------------
void MsLinkUserCall()
{
union REGS r;
struct SREGS sr;

*((int *)(0x0000040E))=FP_SEG(&MouseActive);
r.x.ax=0x0C;
r.x.cx=0x001F;
r.x.dx=FP_OFF(mscall);
sr.es=FP_SEG(mscall);
int86x(0x33,&r,&r,&sr);
}
//-------------------------------------------------------
int MsInstall()
{
void far *address;
union REGS regs;

address=getvect(0x33);
if((address==NULL)||(*(unsigned char *)address==0xCF)) return 0;
else {
regs.x.ax=0;
int86(0x33,&regs,&regs);
return regs.x.ax;
}
}
//-------------------------------------------------------
void MsShow()
{
union REGS regs;

regs.x.ax=1;
int86(0x33,&regs,&regs);
}
//-------------------------------------------------------
void MsHide()
{
union REGS regs;

regs.x.ax=2;
int86(0x33,&regs,&regs);
}
//-------------------------------------------------------
void MsSetLoc(x,y)
unsigned int x,y;
{
union REGS regs;

regs.x.ax=4;
regs.x.cx=x;
regs.x.dx=y;
int86(0x33,&regs,&regs);
}
//-------------------------------------------------------
void MsSetHoriLimit(l,r)
unsigned int l,r;
{
union REGS regs;

regs.x.ax=7;
regs.x.cx=l;
regs.x.dx=r;
int86(0x33,&regs,&regs);
}
//-------------------------------------------------------
void MsSetVertLimit(t,b)
unsigned int t,b;
{
union REGS regs;

regs.x.ax=8;
regs.x.cx=t;
regs.x.dx=b;
int86(0x33,&regs,&regs);
}
//-------------------------------------------------------
void main()
{
if (!MsInstall()) {
printf("I need a mouse.\n");
return;
}
clrscr();
MsLinkUserCall();
MsSetHoriLimit(0,638);
MsSetVertLimit(0,192);
MsSetLoc(0,0);
MsShow();
while (1) {
if (kbhit()) {
if (getch()==27) break;
}
if (MouseActive==YES) {
if (MouseMask&LEFT_DOWN) {
MsHide();printf(" LEFT_DOWN");MsShow();
}
if (MouseMask&LEFT_UP) {
MsHide();printf(" LEFT_UP");MsShow();
}
if (MouseMask&RIGHT_DOWN) {
MsHide();printf(" RIGHT_DOWN");MsShow();
}
if (MouseMask&RIGHT_UP) {
MsHide();printf(" RIGHT_UP");MsShow();
}
if (MouseButton&1) {
MsHide();printf(" LEFT_DRAG");MsShow();
}
if (MouseButton&2) {
MsHide();printf(" RIGHT_DRAG");MsShow();
}
if (MouseMask&CURSOR_MOVE) {
MsHide();printf(" MOVE_TO(%3d,%3d)",MouseX,MouseY);MsShow();
}
MsHide();printf("\n");MsShow();
MouseActive=NO;
}
}
MsHide();
MsInstall();
}

#14


VC++早就不支持生成16位程序,不论dos16、win16,你嵌入的是dos 16位汇编,根本不可能通过,而且还有一部分MASM语法在嵌入汇编中不支持。

#15


引用 13 楼 zhao4zhong1 的回复:
仅供参考:
#pragma option -N-
//-------------------------------------------------------
#include <conio.h>
#include <dos.h>
#include <stdio.h>
//-------------------------------------------------------
#define YES         1
#define NO          0
#define CURSOR_MOVE 1
#define LEFT_DOWN   2
#define LEFT_UP     4
#define RIGHT_DOWN  8
#define RIGHT_UP    16
int MouseActive=NO,MouseMask,MouseButton,MouseX,MouseY;
//-------------------------------------------------------
void far mscall()
{
asm {
push ds
push si
xor si,si
mov ds,si
mov si,[0x40E]
mov ds,si
cmp ax,MouseMask
jne changed
cmp bx,MouseButton
jne changed
cmp cx,MouseX
jne changed
cmp dx,MouseY
je nochange
}
changed:
asm {
mov MouseMask,ax
mov MouseButton,bx
mov MouseX,cx
mov MouseY,dx
mov MouseActive,YES
jmp end
}
nochange:
asm {
mov MouseActive,NO
}
end:
asm {
pop si
pop ds
}
}
//-------------------------------------------------------
void MsLinkUserCall()
{
union REGS r;
struct SREGS sr;

*((int *)(0x0000040E))=FP_SEG(&MouseActive);
r.x.ax=0x0C;
r.x.cx=0x001F;
r.x.dx=FP_OFF(mscall);
sr.es=FP_SEG(mscall);
int86x(0x33,&r,&r,&sr);
}
//-------------------------------------------------------
int MsInstall()
{
void far *address;
union REGS regs;

address=getvect(0x33);
if((address==NULL)||(*(unsigned char *)address==0xCF)) return 0;
else {
regs.x.ax=0;
int86(0x33,&regs,&regs);
return regs.x.ax;
}
}
//-------------------------------------------------------
void MsShow()
{
union REGS regs;

regs.x.ax=1;
int86(0x33,&regs,&regs);
}
//-------------------------------------------------------
void MsHide()
{
union REGS regs;

regs.x.ax=2;
int86(0x33,&regs,&regs);
}
//-------------------------------------------------------
void MsSetLoc(x,y)
unsigned int x,y;
{
union REGS regs;

regs.x.ax=4;
regs.x.cx=x;
regs.x.dx=y;
int86(0x33,&regs,&regs);
}
//-------------------------------------------------------
void MsSetHoriLimit(l,r)
unsigned int l,r;
{
union REGS regs;

regs.x.ax=7;
regs.x.cx=l;
regs.x.dx=r;
int86(0x33,&regs,&regs);
}
//-------------------------------------------------------
void MsSetVertLimit(t,b)
unsigned int t,b;
{
union REGS regs;

regs.x.ax=8;
regs.x.cx=t;
regs.x.dx=b;
int86(0x33,&regs,&regs);
}
//-------------------------------------------------------
void main()
{
if (!MsInstall()) {
printf("I need a mouse.\n");
return;
}
clrscr();
MsLinkUserCall();
MsSetHoriLimit(0,638);
MsSetVertLimit(0,192);
MsSetLoc(0,0);
MsShow();
while (1) {
if (kbhit()) {
if (getch()==27) break;
}
if (MouseActive==YES) {
if (MouseMask&LEFT_DOWN) {
MsHide();printf(" LEFT_DOWN");MsShow();
}
if (MouseMask&LEFT_UP) {
MsHide();printf(" LEFT_UP");MsShow();
}
if (MouseMask&RIGHT_DOWN) {
MsHide();printf(" RIGHT_DOWN");MsShow();
}
if (MouseMask&RIGHT_UP) {
MsHide();printf(" RIGHT_UP");MsShow();
}
if (MouseButton&1) {
MsHide();printf(" LEFT_DRAG");MsShow();
}
if (MouseButton&2) {
MsHide();printf(" RIGHT_DRAG");MsShow();
}
if (MouseMask&CURSOR_MOVE) {
MsHide();printf(" MOVE_TO(%3d,%3d)",MouseX,MouseY);MsShow();
}
MsHide();printf("\n");MsShow();
MouseActive=NO;
}
}
MsHide();
MsInstall();
}
赵老师,你这个程序太有用了。之前我看了一堆如何嵌入的,总是晕头转向,正在用“alt+8”来盗取汇编源代码呢,突然看见这个程序,原来如此啊。看来在开学之前完成任务的可能性进一步增强了。谢谢你,赵老师。

#16


D:\BC\flc>dir mouse*.c
 驱动器 D 中的卷是 Q_HD2_8
 卷的序列号是 54FC-A4FD

 D:\BC\flc 的目录

1998-03-31  14:55             3,428 MOUSETST.C
               1 个文件          3,428 字节
               0 个目录 16,783,536,128 可用字节

D:\BC\flc>
如何把汇编程序嵌入到C语言中

#17


提醒:
Win7下需要在DosBox中运行BC++3.1或TC

WinXP下,建一个批处理bc.bat,内容为下面两行,放在bc.exe同目录下,再将bc.bat发送到桌面快捷方式:
del tc*.swp >NUL
start command /c bc.exe
如果想在IDE里面使用鼠标,还应将快捷方式属性中的快速编辑模式关掉。

#18


引用 17 楼 zhao4zhong1 的回复:
提醒:
Win7下需要在DosBox中运行BC++3.1或TC

WinXP下,建一个批处理bc.bat,内容为下面两行,放在bc.exe同目录下,再将bc.bat发送到桌面快捷方式:
del tc*.swp >NUL
start command /c bc.exe
如果想在IDE里面使用鼠标,还应将快捷方式属性中的快速编辑模式关掉。
啊,赵老师,你说的我不太懂。嗯,首先你这个程序我只是看了他的结构,如何在C语言中整段的定义使用汇编语言的。对于程序的内容我没有细看,刚才你一说与鼠标相关的话题,我没听懂。你这个程序是讲如何在BC下使用鼠标吗?可是我记得BC下本来就可以使用鼠标啊。 如何把汇编程序嵌入到C语言中

#19


引用 18 楼 chimenghuanzhe 的回复:
Quote: 引用 17 楼 zhao4zhong1 的回复:

提醒:
Win7下需要在DosBox中运行BC++3.1或TC

WinXP下,建一个批处理bc.bat,内容为下面两行,放在bc.exe同目录下,再将bc.bat发送到桌面快捷方式:
del tc*.swp >NUL
start command /c bc.exe
如果想在IDE里面使用鼠标,还应将快捷方式属性中的快速编辑模式关掉。
啊,赵老师,你说的我不太懂。嗯,首先你这个程序我只是看了他的结构,如何在C语言中整段的定义使用汇编语言的。对于程序的内容我没有细看,刚才你一说与鼠标相关的话题,我没听懂。你这个程序是讲如何在BC下使用鼠标吗?可是我记得BC下本来就可以使用鼠标啊。 如何把汇编程序嵌入到C语言中

我是担心你在比如Win7下或Win7 64位下用不了BC

#20


引用 19 楼 zhao4zhong1 的回复:
Quote: 引用 18 楼 chimenghuanzhe 的回复:

Quote: 引用 17 楼 zhao4zhong1 的回复:

提醒:
Win7下需要在DosBox中运行BC++3.1或TC

WinXP下,建一个批处理bc.bat,内容为下面两行,放在bc.exe同目录下,再将bc.bat发送到桌面快捷方式:
del tc*.swp >NUL
start command /c bc.exe
如果想在IDE里面使用鼠标,还应将快捷方式属性中的快速编辑模式关掉。
啊,赵老师,你说的我不太懂。嗯,首先你这个程序我只是看了他的结构,如何在C语言中整段的定义使用汇编语言的。对于程序的内容我没有细看,刚才你一说与鼠标相关的话题,我没听懂。你这个程序是讲如何在BC下使用鼠标吗?可是我记得BC下本来就可以使用鼠标啊。 如何把汇编程序嵌入到C语言中

我是担心你在比如Win7下或Win7 64位下用不了BC


引用 19 楼 zhao4zhong1 的回复:
Quote: 引用 18 楼 chimenghuanzhe 的回复:

Quote: 引用 17 楼 zhao4zhong1 的回复:

提醒:
Win7下需要在DosBox中运行BC++3.1或TC

WinXP下,建一个批处理bc.bat,内容为下面两行,放在bc.exe同目录下,再将bc.bat发送到桌面快捷方式:
del tc*.swp >NUL
start command /c bc.exe
如果想在IDE里面使用鼠标,还应将快捷方式属性中的快速编辑模式关掉。
啊,赵老师,你说的我不太懂。嗯,首先你这个程序我只是看了他的结构,如何在C语言中整段的定义使用汇编语言的。对于程序的内容我没有细看,刚才你一说与鼠标相关的话题,我没听懂。你这个程序是讲如何在BC下使用鼠标吗?可是我记得BC下本来就可以使用鼠标啊。 如何把汇编程序嵌入到C语言中

我是担心你在比如Win7下或Win7 64位下用不了BC
我用的是VS2010啊,VC++6.0在win7下面无法使用,所以安装了VS2010,(因为没有找到单独的VC2010),虽然很不熟悉。至于汇编语言,我只是准备编几个子函数,加减乘除,每个子函数把参数传递进去,然后用汇编计算,然后再把结果传出来。这样,函数的主体部分还是用C编写的,不过,里面涉及到cos函数,我看它的源代码,是按照泰勒公式展开的,一直展开到了x的14次方,我的天哪,我这个x本身就有100位,最少也是64个字节,即64位(我是用unsigned char型数组),然后它再14次方,要多少位,有可能会冲到1400位,然后,Oh,my god!我相信的电脑会崩溃的。

#21


VS2010只能嵌入32位汇编,嵌入不了16位或64位汇编。
32位汇编参考下面:
X86和X87汇编指令大全(有注释)
---------- 一、数据传输指令 ----------------------------------------------------
它们在存贮器和寄存器、寄存器和输入输出端口之间传送数据.
1. 通用数据传送指令.
MOV 传送字或字节.
MOVSX 先符号扩展,再传送.
MOVZX 先零扩展,再传送.
PUSH 把字压入堆栈.
POP 把字弹出堆栈.
PUSHA 把AX,CX,DX,BX,SP,BP,SI,DI依次压入堆栈.
POPA 把DI,SI,BP,SP,BX,DX,CX,AX依次弹出堆栈.
PUSHAD 把EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI依次压入堆栈.
POPAD 把EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX依次弹出堆栈.
BSWAP 交换32位寄存器里字节的顺序
XCHG 交换字或字节.(至少有一个操作数为寄存器,段寄存器不可作为操作数)
CMPXCHG 比较并交换操作数.(第二个操作数必须为累加器AL/AX/EAX)
XADD 先交换再累加.(结果在第一个操作数里)
XLAT 字节查表转换.----BX指向一张256字节的表的起点,AL为表的索引值(0-255,即0-FFH);返回AL为查表结果.([BX+AL]->AL)
2. 输入输出端口传送指令.
IN I/O端口输入. ( 语法: IN 累加器, {端口号│DX} )
OUT I/O端口输出. ( 语法: OUT {端口号│DX},累加器 )输入输出端口由立即方式指定时, 其范围是 0-255; 由寄存器 DX 指定时,其范围是 0-65535.
3. 目的地址传送指令.
LEA 装入有效地址.例: LEA DX,string ;把偏移地址存到DX.
LDS 传送目标指针,把指针内容装入DS.例: LDS SI,string ;把段地址:偏移地址存到DS:SI.
LES 传送目标指针,把指针内容装入ES.例: LES DI,string ;把段地址:偏移地址存到ES:DI.
LFS 传送目标指针,把指针内容装入FS.例: LFS DI,string ;把段地址:偏移地址存到FS:DI.
LGS 传送目标指针,把指针内容装入GS.例: LGS DI,string ;把段地址:偏移地址存到GS:DI.
LSS 传送目标指针,把指针内容装入SS.例: LSS DI,string ;把段地址:偏移地址存到SS:DI.
4. 标志传送指令.
LAHF 标志寄存器传送,把标志装入AH.
SAHF 标志寄存器传送,把AH内容装入标志寄存器.
PUSHF 标志入栈.
POPF 标志出栈.
PUSHD 32位标志入栈.
POPD 32位标志出栈.
---------- 二、算术运算指令 ----------------------------------------------------
ADD 加法.
ADC 带进位加法.
INC 加 1.
AAA 加法的ASCII码调整.
DAA 加法的十进制调整.
SUB 减法.
SBB 带借位减法.
DEC 减 1.
NEG 求反(以 0 减之).
CMP 比较.(两操作数作减法,仅修改标志位,不回送结果).
AAS 减法的ASCII码调整.
DAS 减法的十进制调整.
MUL 无符号乘法.结果回送AH和AL(字节运算),或DX和AX(字运算),
IMUL 整数乘法.结果回送AH和AL(字节运算),或DX和AX(字运算),
AAM 乘法的ASCII码调整.
DIV 无符号除法.结果回送:商回送AL,余数回送AH, (字节运算);或 商回送AX,余数回送DX, (字运算).
IDIV 整数除法.结果回送:商回送AL,余数回送AH, (字节运算);或 商回送AX,余数回送DX, (字运算).
AAD 除法的ASCII码调整.
CBW 字节转换为字. (把AL中字节的符号扩展到AH中去)
CWD 字转换为双字. (把AX中的字的符号扩展到DX中去)
CWDE 字转换为双字. (把AX中的字符号扩展到EAX中去)
CDQ 双字扩展. (把EAX中的字的符号扩展到EDX中去)
---------- 三、逻辑运算指令 ----------------------------------------------------
AND 与运算.
OR 或运算.
XOR 异或运算.
NOT 取反.
TEST 测试.(两操作数作与运算,仅修改标志位,不回送结果).
SHL 逻辑左移.
SAL 算术左移.(=SHL)
SHR 逻辑右移.
SAR 算术右移.(=SHR)
ROL 循环左移.
ROR 循环右移.
RCL 通过进位的循环左移.
RCR 通过进位的循环右移.
  以上八种移位指令,其移位次数可达255次.
  移位一次时, 可直接用操作码. 如 SHL AX,1.
  移位>1次时, 则由寄存器CL给出移位次数.
  如 MOV CL,04 SHL AX,CL
---------- 四、串指令 ----------------------------------------------------------
  DS:SI 源串段寄存器 :源串变址.
  ES:DI 目标串段寄存器:目标串变址.
  CX 重复次数计数器.
  AL/AX 扫描值.
  D标志 0表示重复操作中SI和DI应自动增量; 1表示应自动减量.
  Z标志 用来控制扫描或比较操作的结束.
MOVS 串传送.( MOVSB 传送字符. MOVSW 传送字. MOVSD 传送双字. )
CMPS 串比较.( CMPSB 比较字符. CMPSW 比较字. )
SCAS 串扫描.把AL或AX的内容与目标串作比较,比较结果反映在标志位.
LODS 装入串.把源串中的元素(字或字节)逐一装入AL或AX中.( LODSB 传送字符. LODSW 传送字. LODSD 传送双字. )
STOS 保存串.是LODS的逆过程.
REP 当CX/ECX<>0时重复.
REPE/REPZ 当ZF=1或比较结果相等,且CX/ECX<>0时重复.
REPNE/REPNZ 当ZF=0或比较结果不相等,且CX/ECX<>0时重复.
REPC 当CF=1且CX/ECX<>0时重复.
REPNC 当CF=0且CX/ECX<>0时重复.
---------- 五、程序转移指令 ----------------------------------------------------
1. 无条件转移指令 (长转移)
JMP 无条件转移指令
CALL 过程调用
RET/RETF 过程返回.
2. 条件转移指令 (短转移,-128到+127的距离内)( 当且仅当(SF XOR OF)=1时,OP1<OP2 )
JA/JNBE 不小于或不等于时转移.
JAE/JNB 大于或等于转移.
JB/JNAE 小于转移.
JBE/JNA 小于或等于转移.
以上四条,测试无符号整数运算的结果(标志C和Z).
JG/JNLE 大于转移.
JGE/JNL 大于或等于转移.
JL/JNGE 小于转移.
JLE/JNG 小于或等于转移.
以上四条,测试带符号整数运算的结果(标志S,O和Z).
JE/JZ 等于转移.
JNE/JNZ 不等于时转移.
JC 有进位时转移.
JNC 无进位时转移.
JNO 不溢出时转移.
JNP/JPO 奇偶性为奇数时转移.
JNS 符号位为 "0" 时转移.
JO 溢出转移.
JP/JPE 奇偶性为偶数时转移.
JS 符号位为 "1" 时转移.
3. 循环控制指令(短转移)
LOOP CX不为零时循环.
LOOPE/LOOPZ CX不为零且标志Z=1时循环.
LOOPNE/LOOPNZ CX不为零且标志Z=0时循环.
JCXZ CX为零时转移.
JECXZ ECX为零时转移.
4. 中断指令
INT 中断指令
INTO 溢出中断
IRET 中断返回
5. 处理器控制指令
HLT 处理器暂停, 直到出现中断或复位信号才继续.
WAIT 当芯片引线TEST为高电平时使CPU进入等待状态.
ESC 转换到外处理器.
LOCK *总线.
NOP 空操作.
STC 置进位标志位.
CLC 清进位标志位.
CMC 进位标志取反.
STD 置方向标志位.
CLD 清方向标志位.
STI 置中断允许位.
CLI 清中断允许位.
---------- 六、伪指令 ----------------------------------------------------------
DW 定义字(2字节).
PROC 定义过程.
ENDP 过程结束.
SEGMENT 定义段.
ASSUME 建立段寄存器寻址.
ENDS 段结束.
END 程序结束.
---------- 七、处理机控制指令:标志处理指令 ------------------------------------
CLC 进位位置0指令
CMC 进位位求反指令
STC 进位位置为1指令
CLD 方向标志置1指令
STD 方向标志位置1指令
CLI 中断标志置0指令
STI 中断标志置1指令
NOP 无操作
HLT 停机
WAIT 等待
ESC 换码
LOCK *
========== 浮点运算指令集 ======================================================
---------- 一、控制指令(带9B的控制指令前缀F变为FN时浮点不检查,机器码去掉9B)----
FINIT   初始化浮点部件    机器码  9B DB E3
FCLEX   清除异常    机器码  9B DB E2
FDISI   浮点检查禁止中断    机器码  9B DB E1
FENI   浮点检查禁止中断二    机器码  9B DB E0
WAIT   同步CPU和FPU    机器码  9B
FWAIT   同步CPU和FPU    机器码  D9 D0
FNOP   无操作    机器码  DA E9
FXCH   交换ST(0)和ST(1)    机器码  D9 C9
FXCH ST(i)   交换ST(0)和ST(i)    机器码  D9 C1iii
FSTSW ax   状态字到ax    机器码  9B DF E0
FSTSW word ptr mem  状态字到mem    机器码  9B DD mm111mmm
FLDCW word ptr mem  mem到状态字    机器码  D9 mm101mmm
FSTCW word ptr mem  控制字到mem    机器码  9B D9 mm111mmm

FLDENV word ptr mem  mem到全环境    机器码  D9 mm100mmm
FSTENV word ptr mem  全环境到mem    机器码  9B D9 mm110mmm
FRSTOR word ptr mem  mem到FPU状态    机器码  DD mm100mmm
FSAVE word ptr mem  FPU状态到mem    机器码  9B DD mm110mmm

FFREE ST(i)   标志ST(i)未使用    机器码  DD C0iii
FDECSTP   减少栈指针1->0 2->1    机器码  D9 F6
FINCSTP   增加栈指针0->1 1->2    机器码  D9 F7
FSETPM   浮点设置保护    机器码  DB E4
---------- 二、数据传送指令 ----------------------------------------------------
FLDZ   将0.0装入ST(0)    机器码  D9 EE
FLD1   将1.0装入ST(0)    机器码  D9 E8
FLDPI   将π装入ST(0)    机器码  D9 EB
FLDL2T   将ln10/ln2装入ST(0)    机器码  D9 E9
FLDL2E   将1/ln2装入ST(0)    机器码  D9 EA
FLDLG2   将ln2/ln10装入ST(0)    机器码  D9 EC
FLDLN2   将ln2装入ST(0)    机器码  D9 ED

FLD    real4 ptr mem  装入mem的单精度浮点数    机器码  D9 mm000mmm
FLD    real8 ptr mem  装入mem的双精度浮点数    机器码  DD mm000mmm
FLD   real10 ptr mem  装入mem的十字节浮点数    机器码  DB mm101mmm

FILD word ptr mem  装入mem的二字节整数    机器码  DF mm000mmm
FILD   dword ptr mem  装入mem的四字节整数    机器码  DB mm000mmm
FILD   qword ptr mem  装入mem的八字节整数    机器码  DF mm101mmm

FBLD   tbyte ptr mem  装入mem的十字节BCD数    机器码  DF mm100mmm

FST    real4 ptr mem  保存单精度浮点数到mem    机器码  D9 mm010mmm
FST    real8 ptr mem  保存双精度浮点数到mem    机器码  DD mm010mmm

FIST word ptr mem  保存二字节整数到mem    机器码  DF mm010mmm
FIST   dword ptr mem  保存四字节整数到mem    机器码  DB mm010mmm

FSTP   real4 ptr mem  保存单精度浮点数到mem并出栈    机器码  D9 mm011mmm
FSTP   real8 ptr mem  保存双精度浮点数到mem并出栈    机器码  DD mm011mmm
FSTP  real10 ptr mem  保存十字节浮点数到mem并出栈    机器码  DB mm111mmm

FISTP word ptr mem  保存二字节整数到mem并出栈    机器码  DF mm011mmm
FISTP  dword ptr mem  保存四字节整数到mem并出栈    机器码  DB mm011mmm
FISTP  qword ptr mem  保存八字节整数到mem并出栈    机器码  DF mm111mmm

FBSTP  tbyte ptr mem  保存十字节BCD数到mem并出栈    机器码  DF mm110mmm

FCMOVB   ST(0),ST(i) <时传送    机器码  DA C0iii
FCMOVBE   ST(0),ST(i) <=时传送    机器码  DA D0iii
FCMOVE   ST(0),ST(i) =时传送    机器码  DA C1iii
FCMOVNB   ST(0),ST(i) >=时传送    机器码  DB C0iii
FCMOVNBE   ST(0),ST(i) >时传送    机器码  DB D0iii
FCMOVNE   ST(0),ST(i) !=时传送    机器码  DB C1iii
FCMOVNU   ST(0),ST(i) 有序时传送    机器码  DB D1iii
FCMOVU   ST(0),ST(i) 无序时传送    机器码  DA D1iii
---------- 三、比较指令 --------------------------------------------------------
FCOM   ST(0)-ST(1)    机器码  D8 D1
FCOMI   ST(0),ST(i)  ST(0)-ST(1)    机器码  DB F0iii
FCOMIP   ST(0),ST(i)  ST(0)-ST(1)并出栈   机器码  DF F0iii
FCOM   real4 ptr mem  ST(0)-实数mem    机器码  D8 mm010mmm
FCOM   real8 ptr mem  ST(0)-实数mem    机器码  DC mm010mmm

FICOM word ptr mem  ST(0)-整数mem    机器码  DE mm010mmm
FICOM  dword ptr mem  ST(0)-整数mem    机器码  DA mm010mmm
FICOMP word ptr mem  ST(0)-整数mem并出栈    机器码  DE mm011mmm
FICOMP dword ptr mem  ST(0)-整数mem并出栈    机器码  DA mm011mmm

FTST   ST(0)-0    机器码  D9 E4
FUCOM  ST(i)   ST(0)-ST(i)    机器码  DD E0iii
FUCOMP ST(i)   ST(0)-ST(i)并出栈    机器码  DD E1iii
FUCOMPP   ST(0)-ST(1)并二次出栈    机器码  DA E9
FXAM   ST(0)规格类型    机器码  D9 E5
---------- 四、运算指令 --------------------------------------------------------
FADD   把目的操作数 (直接接在指令后的变量或堆栈缓存器) 与来源操作数 (接在目的操作数后的变量或堆栈缓存器) 相加,并将结果存入目的操作数
FADDP  ST(i),ST   这个指令是使目的操作数加上 ST 缓存器,并弹出 ST 缓存器,而目的操作数必须是堆栈缓存器的其中之一,最后不管目的操作数为何,经弹出一次后,目的操作数会变成上一个堆栈缓存器了
FIADD   FIADD 是把 ST 加上来源操作数,然后再存入 ST 缓存器,来源操作数必须是字组整数或短整数形态的变数

FSUB   减
FSUBP
FSUBR   减数与被减数互换
FSUBRP
FISUB
FISUBR

FMUL   乘
FMULP
FIMUL

FDIV   除
FDIVP
FDIVR
FDIVRP
FIDIV
FIDIVR

FCHS   改变 ST 的正负值

FABS   把 ST 之值取出,取其绝对值后再存回去。

FSQRT   将 ST 之值取出,开根号后再存回去。

FSCALE   这个指令是计算 ST*2^ST(1)之值,再把结果存入 ST 里而 ST(1) 之值不变。ST(1) 必须是在 -32768 到 32768 (-215 到 215 )之间的整数,如果超过这个范围计算结果无法确定,如果不是整数 ST(1) 会先向零舍入成整数再计算。所以为安全起见,最好是由字组整数载入到 ST(1) 里。

FRNDINT   这个指令是把 ST 的数值舍入成整数,FPU 提供四种舍入方式,由 FPU 的控制字组(control word)中的 RC 两个位决定
  RC 舍入控制
  00 四舍五入
  01 向负无限大舍入
  10 向正无限大舍入
  11 向零舍去
================================================================================

#22


引用 21 楼 zhao4zhong1 的回复:
VS2010只能嵌入32位汇编,嵌入不了16位或64位汇编。
32位汇编参考下面:
X86和X87汇编指令大全(有注释)
---------- 一、数据传输指令 ----------------------------------------------------
它们在存贮器和寄存器、寄存器和输入输出端口之间传送数据.
1. 通用数据传送指令.
MOV 传送字或字节.
MOVSX 先符号扩展,再传送.
MOVZX 先零扩展,再传送.
PUSH 把字压入堆栈.
POP 把字弹出堆栈.
PUSHA 把AX,CX,DX,BX,SP,BP,SI,DI依次压入堆栈.
POPA 把DI,SI,BP,SP,BX,DX,CX,AX依次弹出堆栈.
PUSHAD 把EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI依次压入堆栈.
POPAD 把EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX依次弹出堆栈.
BSWAP 交换32位寄存器里字节的顺序
XCHG 交换字或字节.(至少有一个操作数为寄存器,段寄存器不可作为操作数)
CMPXCHG 比较并交换操作数.(第二个操作数必须为累加器AL/AX/EAX)
XADD 先交换再累加.(结果在第一个操作数里)
XLAT 字节查表转换.----BX指向一张256字节的表的起点,AL为表的索引值(0-255,即0-FFH);返回AL为查表结果.([BX+AL]->AL)
2. 输入输出端口传送指令.
IN I/O端口输入. ( 语法: IN 累加器, {端口号│DX} )
OUT I/O端口输出. ( 语法: OUT {端口号│DX},累加器 )输入输出端口由立即方式指定时, 其范围是 0-255; 由寄存器 DX 指定时,其范围是 0-65535.
3. 目的地址传送指令.
LEA 装入有效地址.例: LEA DX,string ;把偏移地址存到DX.
LDS 传送目标指针,把指针内容装入DS.例: LDS SI,string ;把段地址:偏移地址存到DS:SI.
LES 传送目标指针,把指针内容装入ES.例: LES DI,string ;把段地址:偏移地址存到ES:DI.
LFS 传送目标指针,把指针内容装入FS.例: LFS DI,string ;把段地址:偏移地址存到FS:DI.
LGS 传送目标指针,把指针内容装入GS.例: LGS DI,string ;把段地址:偏移地址存到GS:DI.
LSS 传送目标指针,把指针内容装入SS.例: LSS DI,string ;把段地址:偏移地址存到SS:DI.
4. 标志传送指令.
LAHF 标志寄存器传送,把标志装入AH.
SAHF 标志寄存器传送,把AH内容装入标志寄存器.
PUSHF 标志入栈.
POPF 标志出栈.
PUSHD 32位标志入栈.
POPD 32位标志出栈.
---------- 二、算术运算指令 ----------------------------------------------------
ADD 加法.
ADC 带进位加法.
INC 加 1.
AAA 加法的ASCII码调整.
DAA 加法的十进制调整.
SUB 减法.
SBB 带借位减法.
DEC 减 1.
NEG 求反(以 0 减之).
CMP 比较.(两操作数作减法,仅修改标志位,不回送结果).
AAS 减法的ASCII码调整.
DAS 减法的十进制调整.
MUL 无符号乘法.结果回送AH和AL(字节运算),或DX和AX(字运算),
IMUL 整数乘法.结果回送AH和AL(字节运算),或DX和AX(字运算),
AAM 乘法的ASCII码调整.
DIV 无符号除法.结果回送:商回送AL,余数回送AH, (字节运算);或 商回送AX,余数回送DX, (字运算).
IDIV 整数除法.结果回送:商回送AL,余数回送AH, (字节运算);或 商回送AX,余数回送DX, (字运算).
AAD 除法的ASCII码调整.
CBW 字节转换为字. (把AL中字节的符号扩展到AH中去)
CWD 字转换为双字. (把AX中的字的符号扩展到DX中去)
CWDE 字转换为双字. (把AX中的字符号扩展到EAX中去)
CDQ 双字扩展. (把EAX中的字的符号扩展到EDX中去)
---------- 三、逻辑运算指令 ----------------------------------------------------
AND 与运算.
OR 或运算.
XOR 异或运算.
NOT 取反.
TEST 测试.(两操作数作与运算,仅修改标志位,不回送结果).
SHL 逻辑左移.
SAL 算术左移.(=SHL)
SHR 逻辑右移.
SAR 算术右移.(=SHR)
ROL 循环左移.
ROR 循环右移.
RCL 通过进位的循环左移.
RCR 通过进位的循环右移.
  以上八种移位指令,其移位次数可达255次.
  移位一次时, 可直接用操作码. 如 SHL AX,1.
  移位>1次时, 则由寄存器CL给出移位次数.
  如 MOV CL,04 SHL AX,CL
---------- 四、串指令 ----------------------------------------------------------
  DS:SI 源串段寄存器 :源串变址.
  ES:DI 目标串段寄存器:目标串变址.
  CX 重复次数计数器.
  AL/AX 扫描值.
  D标志 0表示重复操作中SI和DI应自动增量; 1表示应自动减量.
  Z标志 用来控制扫描或比较操作的结束.
MOVS 串传送.( MOVSB 传送字符. MOVSW 传送字. MOVSD 传送双字. )
CMPS 串比较.( CMPSB 比较字符. CMPSW 比较字. )
SCAS 串扫描.把AL或AX的内容与目标串作比较,比较结果反映在标志位.
LODS 装入串.把源串中的元素(字或字节)逐一装入AL或AX中.( LODSB 传送字符. LODSW 传送字. LODSD 传送双字. )
STOS 保存串.是LODS的逆过程.
REP 当CX/ECX<>0时重复.
REPE/REPZ 当ZF=1或比较结果相等,且CX/ECX<>0时重复.
REPNE/REPNZ 当ZF=0或比较结果不相等,且CX/ECX<>0时重复.
REPC 当CF=1且CX/ECX<>0时重复.
REPNC 当CF=0且CX/ECX<>0时重复.
---------- 五、程序转移指令 ----------------------------------------------------
1. 无条件转移指令 (长转移)
JMP 无条件转移指令
CALL 过程调用
RET/RETF 过程返回.
2. 条件转移指令 (短转移,-128到+127的距离内)( 当且仅当(SF XOR OF)=1时,OP1<OP2 )
JA/JNBE 不小于或不等于时转移.
JAE/JNB 大于或等于转移.
JB/JNAE 小于转移.
JBE/JNA 小于或等于转移.
以上四条,测试无符号整数运算的结果(标志C和Z).
JG/JNLE 大于转移.
JGE/JNL 大于或等于转移.
JL/JNGE 小于转移.
JLE/JNG 小于或等于转移.
以上四条,测试带符号整数运算的结果(标志S,O和Z).
JE/JZ 等于转移.
JNE/JNZ 不等于时转移.
JC 有进位时转移.
JNC 无进位时转移.
JNO 不溢出时转移.
JNP/JPO 奇偶性为奇数时转移.
JNS 符号位为 "0" 时转移.
JO 溢出转移.
JP/JPE 奇偶性为偶数时转移.
JS 符号位为 "1" 时转移.
3. 循环控制指令(短转移)
LOOP CX不为零时循环.
LOOPE/LOOPZ CX不为零且标志Z=1时循环.
LOOPNE/LOOPNZ CX不为零且标志Z=0时循环.
JCXZ CX为零时转移.
JECXZ ECX为零时转移.
4. 中断指令
INT 中断指令
INTO 溢出中断
IRET 中断返回
5. 处理器控制指令
HLT 处理器暂停, 直到出现中断或复位信号才继续.
WAIT 当芯片引线TEST为高电平时使CPU进入等待状态.
ESC 转换到外处理器.
LOCK *总线.
NOP 空操作.
STC 置进位标志位.
CLC 清进位标志位.
CMC 进位标志取反.
STD 置方向标志位.
CLD 清方向标志位.
STI 置中断允许位.
CLI 清中断允许位.
---------- 六、伪指令 ----------------------------------------------------------
DW 定义字(2字节).
PROC 定义过程.
ENDP 过程结束.
SEGMENT 定义段.
ASSUME 建立段寄存器寻址.
ENDS 段结束.
END 程序结束.
---------- 七、处理机控制指令:标志处理指令 ------------------------------------
CLC 进位位置0指令
CMC 进位位求反指令
STC 进位位置为1指令
CLD 方向标志置1指令
STD 方向标志位置1指令
CLI 中断标志置0指令
STI 中断标志置1指令
NOP 无操作
HLT 停机
WAIT 等待
ESC 换码
LOCK *
========== 浮点运算指令集 ======================================================
---------- 一、控制指令(带9B的控制指令前缀F变为FN时浮点不检查,机器码去掉9B)----
FINIT   初始化浮点部件    机器码  9B DB E3
FCLEX   清除异常    机器码  9B DB E2
FDISI   浮点检查禁止中断    机器码  9B DB E1
FENI   浮点检查禁止中断二    机器码  9B DB E0
WAIT   同步CPU和FPU    机器码  9B
FWAIT   同步CPU和FPU    机器码  D9 D0
FNOP   无操作    机器码  DA E9
FXCH   交换ST(0)和ST(1)    机器码  D9 C9
FXCH ST(i)   交换ST(0)和ST(i)    机器码  D9 C1iii
FSTSW ax   状态字到ax    机器码  9B DF E0
FSTSW word ptr mem  状态字到mem    机器码  9B DD mm111mmm
FLDCW word ptr mem  mem到状态字    机器码  D9 mm101mmm
FSTCW word ptr mem  控制字到mem    机器码  9B D9 mm111mmm

FLDENV word ptr mem  mem到全环境    机器码  D9 mm100mmm
FSTENV word ptr mem  全环境到mem    机器码  9B D9 mm110mmm
FRSTOR word ptr mem  mem到FPU状态    机器码  DD mm100mmm
FSAVE word ptr mem  FPU状态到mem    机器码  9B DD mm110mmm

FFREE ST(i)   标志ST(i)未使用    机器码  DD C0iii
FDECSTP   减少栈指针1->0 2->1    机器码  D9 F6
FINCSTP   增加栈指针0->1 1->2    机器码  D9 F7
FSETPM   浮点设置保护    机器码  DB E4
---------- 二、数据传送指令 ----------------------------------------------------
FLDZ   将0.0装入ST(0)    机器码  D9 EE
FLD1   将1.0装入ST(0)    机器码  D9 E8
FLDPI   将π装入ST(0)    机器码  D9 EB
FLDL2T   将ln10/ln2装入ST(0)    机器码  D9 E9
FLDL2E   将1/ln2装入ST(0)    机器码  D9 EA
FLDLG2   将ln2/ln10装入ST(0)    机器码  D9 EC
FLDLN2   将ln2装入ST(0)    机器码  D9 ED

FLD    real4 ptr mem  装入mem的单精度浮点数    机器码  D9 mm000mmm
FLD    real8 ptr mem  装入mem的双精度浮点数    机器码  DD mm000mmm
FLD   real10 ptr mem  装入mem的十字节浮点数    机器码  DB mm101mmm

FILD word ptr mem  装入mem的二字节整数    机器码  DF mm000mmm
FILD   dword ptr mem  装入mem的四字节整数    机器码  DB mm000mmm
FILD   qword ptr mem  装入mem的八字节整数    机器码  DF mm101mmm

FBLD   tbyte ptr mem  装入mem的十字节BCD数    机器码  DF mm100mmm

FST    real4 ptr mem  保存单精度浮点数到mem    机器码  D9 mm010mmm
FST    real8 ptr mem  保存双精度浮点数到mem    机器码  DD mm010mmm

FIST word ptr mem  保存二字节整数到mem    机器码  DF mm010mmm
FIST   dword ptr mem  保存四字节整数到mem    机器码  DB mm010mmm

FSTP   real4 ptr mem  保存单精度浮点数到mem并出栈    机器码  D9 mm011mmm
FSTP   real8 ptr mem  保存双精度浮点数到mem并出栈    机器码  DD mm011mmm
FSTP  real10 ptr mem  保存十字节浮点数到mem并出栈    机器码  DB mm111mmm

FISTP word ptr mem  保存二字节整数到mem并出栈    机器码  DF mm011mmm
FISTP  dword ptr mem  保存四字节整数到mem并出栈    机器码  DB mm011mmm
FISTP  qword ptr mem  保存八字节整数到mem并出栈    机器码  DF mm111mmm

FBSTP  tbyte ptr mem  保存十字节BCD数到mem并出栈    机器码  DF mm110mmm

FCMOVB   ST(0),ST(i) <时传送    机器码  DA C0iii
FCMOVBE   ST(0),ST(i) <=时传送    机器码  DA D0iii
FCMOVE   ST(0),ST(i) =时传送    机器码  DA C1iii
FCMOVNB   ST(0),ST(i) >=时传送    机器码  DB C0iii
FCMOVNBE   ST(0),ST(i) >时传送    机器码  DB D0iii
FCMOVNE   ST(0),ST(i) !=时传送    机器码  DB C1iii
FCMOVNU   ST(0),ST(i) 有序时传送    机器码  DB D1iii
FCMOVU   ST(0),ST(i) 无序时传送    机器码  DA D1iii
---------- 三、比较指令 --------------------------------------------------------
FCOM   ST(0)-ST(1)    机器码  D8 D1
FCOMI   ST(0),ST(i)  ST(0)-ST(1)    机器码  DB F0iii
FCOMIP   ST(0),ST(i)  ST(0)-ST(1)并出栈   机器码  DF F0iii
FCOM   real4 ptr mem  ST(0)-实数mem    机器码  D8 mm010mmm
FCOM   real8 ptr mem  ST(0)-实数mem    机器码  DC mm010mmm

FICOM word ptr mem  ST(0)-整数mem    机器码  DE mm010mmm
FICOM  dword ptr mem  ST(0)-整数mem    机器码  DA mm010mmm
FICOMP word ptr mem  ST(0)-整数mem并出栈    机器码  DE mm011mmm
FICOMP dword ptr mem  ST(0)-整数mem并出栈    机器码  DA mm011mmm

FTST   ST(0)-0    机器码  D9 E4
FUCOM  ST(i)   ST(0)-ST(i)    机器码  DD E0iii
FUCOMP ST(i)   ST(0)-ST(i)并出栈    机器码  DD E1iii
FUCOMPP   ST(0)-ST(1)并二次出栈    机器码  DA E9
FXAM   ST(0)规格类型    机器码  D9 E5
---------- 四、运算指令 --------------------------------------------------------
FADD   把目的操作数 (直接接在指令后的变量或堆栈缓存器) 与来源操作数 (接在目的操作数后的变量或堆栈缓存器) 相加,并将结果存入目的操作数
FADDP  ST(i),ST   这个指令是使目的操作数加上 ST 缓存器,并弹出 ST 缓存器,而目的操作数必须是堆栈缓存器的其中之一,最后不管目的操作数为何,经弹出一次后,目的操作数会变成上一个堆栈缓存器了
FIADD   FIADD 是把 ST 加上来源操作数,然后再存入 ST 缓存器,来源操作数必须是字组整数或短整数形态的变数

FSUB   减
FSUBP
FSUBR   减数与被减数互换
FSUBRP
FISUB
FISUBR

FMUL   乘
FMULP
FIMUL

FDIV   除
FDIVP
FDIVR
FDIVRP
FIDIV
FIDIVR

FCHS   改变 ST 的正负值

FABS   把 ST 之值取出,取其绝对值后再存回去。

FSQRT   将 ST 之值取出,开根号后再存回去。

FSCALE   这个指令是计算 ST*2^ST(1)之值,再把结果存入 ST 里而 ST(1) 之值不变。ST(1) 必须是在 -32768 到 32768 (-215 到 215 )之间的整数,如果超过这个范围计算结果无法确定,如果不是整数 ST(1) 会先向零舍入成整数再计算。所以为安全起见,最好是由字组整数载入到 ST(1) 里。

FRNDINT   这个指令是把 ST 的数值舍入成整数,FPU 提供四种舍入方式,由 FPU 的控制字组(control word)中的 RC 两个位决定
  RC 舍入控制
  00 四舍五入
  01 向负无限大舍入
  10 向正无限大舍入
  11 向零舍去
================================================================================
感觉这个指令表比我的书上的都全。当然,之前你说的那个直接翻译成汇编语言那个,绝了。我差点忍不住直接粘上去。

#23


《The Intel 64 and IA-32 Architectures Software Developer's Manual》

#24


再供参考:
#include <stdio.h>
float data[500];
int i;
void main() {
    for (i=0;i<500;i++) {data[i]=1.0f;printf("%g\n",data[i]);}
    __asm {
        push ecx
        push edi
        mov ecx,500
        mov eax,0xBF800000 //-1.0f
        lea edi,data
        rep stosd
        pop edi
        pop ecx
    }
    for (i=0;i<500;i++) printf("%g\n",data[i]);
}

#25


引用 24 楼 zhao4zhong1 的回复:
再供参考:
#include <stdio.h>
float data[500];
int i;
void main() {
    for (i=0;i<500;i++) {data[i]=1.0f;printf("%g\n",data[i]);}
    __asm {
        push ecx
        push edi
        mov ecx,500
        mov eax,0xBF800000 //-1.0f
        lea edi,data
        rep stosd
        pop edi
        pop ecx
    }
    for (i=0;i<500;i++) printf("%g\n",data[i]);
}
赵老师,我想把两个数组,unsigned char a[10],b[8];把他们中的元素,按照a[1]+b[1]=c[1],a[2]+b[2]=c[2],这样计算,把结果放在数组unsigned char c[10]中(a[0]和b[0]不动),请问,用汇编实现这个程序的时候,需要进位的话,是判断OF=1还是判断CF=1,。备注:每个元素如a[i]能存储的数据是从0——255,也就是只有当它彻底存满以后才开始进位的,我想,此时只要判断进位标识符或者溢出标识符就可以了吧?可是,它既是进位又是溢出啊,或者说我对进位和溢出还是没有弄清楚,所以这个题应该是看OF还是CF?如果是减法或者乘法也一样吧?

#26


#27


@赵4老师 
我先是把程序写成了C语言的形式,就是这一段,用来实现大整数相加的。然后在调试的时候,按“alt+8”,反汇编,然后把反汇编的代码粘贴到相应的位置。结果是,C语言产生的结果正确,而嵌入了汇编的程序,结果完全错误。嗯,应该说是从第三位开始出错。
一下是C语言代码,
#include <stdio.h>
#define MAXINT 20

int bigplus(unsigned char a[],unsigned char b[],unsigned char c[]);

int main(int argc, char *argv[])
{
  unsigned char a[MAXINT]={10,5,4,6,5,4,3,2,1,1,1};     //被乘数或被除数
  unsigned char b[MAXINT]={7,7,6,5,4,3,2,1};             //乘数或除数
  unsigned char c[MAXINT],d[MAXINT];                    //c[]存放商,d[]存放余数
  int div=1234;                               //小乘数或小除数
  int k=0;
  int *res=&k;                                //小余数整数指针
  bigplus(a,b,c);
 
  getchar();
  return 0;
}

int bigplus(unsigned char a[],unsigned char b[],unsigned char c[])  //大整数加法
{
    int i,len;
    len=(a[0]>b[0]?a[0]:b[0]);  //a[0] b[0]保存数组长度,len为较长的一个
    for(i=0;i<MAXINT;i++)       //将数组清0
        c[i]=0;
    for (i=1;i<=len;i++)        //计算每一位的值
    {
        c[i]+=(a[i]+b[i]);
        if (c[i]>=10)
        {
           c[i]-=10;            //大于10的取个位
           c[i+1]++;            //高位加1
        }
    }
    if (c[i+1]>0) len++;
        c[0]=len;                //c[0]保存结果数组实际长度
    printf("Big integers add: ");
    for (i=len;i>=1;i--)
                printf("%d",c[i]); //打印结果
        printf("\n");
    return 0;
}



然后是反汇编出来的。
 




,最后是我嵌入的,因为要涉及到跳转,反汇编出来的跳转位置我无法确定,只好把他们分割成不同的小段。

							     

#28


然后是反汇编出来的。
--- d:\documents\visual studio 2010\projects\调试5\调试5\调试5.cpp -------------------
     1: #include <stdio.h>
     2: #define MAXINT 20
     3: 
     4: int bigplus(unsigned char a[],unsigned char b[],unsigned char c[]);
     5: 
     6: int main(int argc, char *argv[])
     7: {
00DB13A0  push        ebp  
00DB13A1  mov         ebp,esp  
00DB13A3  sub         esp,158h  
00DB13A9  push        ebx  
00DB13AA  push        esi  
00DB13AB  push        edi  
00DB13AC  lea         edi,[ebp-158h]  
00DB13B2  mov         ecx,56h  
00DB13B7  mov         eax,0CCCCCCCCh  
00DB13BC  rep stos    dword ptr es:[edi]  
00DB13BE  mov         eax,dword ptr [___security_cookie (0DB7000h)]  
00DB13C3  xor         eax,ebp  
00DB13C5  mov         dword ptr [ebp-4],eax  
     8:   unsigned char a[MAXINT]={10,5,4,6,5,4,3,2,1,1,1};     //被乘数或被除数
00DB13C8  mov         byte ptr [ebp-1Ch],0Ah  
00DB13CC  mov         byte ptr [ebp-1Bh],5  
00DB13D0  mov         byte ptr [ebp-1Ah],4  
00DB13D4  mov         byte ptr [ebp-19h],6  
00DB13D8  mov         byte ptr [ebp-18h],5  
00DB13DC  mov         byte ptr [ebp-17h],4  
00DB13E0  mov         byte ptr [ebp-16h],3  
00DB13E4  mov         byte ptr [ebp-15h],2  
00DB13E8  mov         byte ptr [ebp-14h],1  
00DB13EC  mov         byte ptr [ebp-13h],1  
00DB13F0  mov         byte ptr [ebp-12h],1  
00DB13F4  xor         eax,eax  
00DB13F6  mov         dword ptr [ebp-11h],eax  
00DB13F9  mov         dword ptr [ebp-0Dh],eax  
00DB13FC  mov         byte ptr [ebp-9],al  
     9:   unsigned char b[MAXINT]={7,7,6,5,4,3,2,1};             //乘数或除数
00DB13FF  mov         byte ptr [ebp-38h],7  
00DB1403  mov         byte ptr [ebp-37h],7  
00DB1407  mov         byte ptr [ebp-36h],6  
00DB140B  mov         byte ptr [ebp-35h],5  
00DB140F  mov         byte ptr [ebp-34h],4  
00DB1413  mov         byte ptr [ebp-33h],3  
00DB1417  mov         byte ptr [ebp-32h],2  
00DB141B  mov         byte ptr [ebp-31h],1  
00DB141F  xor         eax,eax  
00DB1421  mov         dword ptr [ebp-30h],eax  
00DB1424  mov         dword ptr [ebp-2Ch],eax  
00DB1427  mov         dword ptr [ebp-28h],eax  
    10:   unsigned char c[MAXINT],d[MAXINT];                    //c[]存放商,d[]存放余数
    11:   int div=1234;                               //小乘数或小除数
00DB142A  mov         dword ptr [ebp-7Ch],4D2h  
    12:   int k=0;
00DB1431  mov         dword ptr [ebp-88h],0  
    13:   int *res=&k;                                //小余数整数指针
00DB143B  lea         eax,[ebp-88h]  
00DB1441  mov         dword ptr [ebp-94h],eax  
    14:   bigplus(a,b,c);
00DB1447  lea         eax,[ebp-54h]  
00DB144A  push        eax  
00DB144B  lea         ecx,[ebp-38h]  
00DB144E  push        ecx  
00DB144F  lea         edx,[ebp-1Ch]  
00DB1452  push        edx  
00DB1453  call        bigplus (0DB11B8h)  
00DB1458  add         esp,0Ch  
    15:  
    16:   getchar();
00DB145B  mov         esi,esp  
00DB145D  call        dword ptr [__imp__getchar (0DB82B8h)]  
00DB1463  cmp         esi,esp  
00DB1465  call        @ILT+295(__RTC_CheckEsp) (0DB112Ch)  
    17:   return 0;
00DB146A  xor         eax,eax  
    18: }
00DB146C  push        edx  
00DB146D  mov         ecx,ebp  
00DB146F  push        eax  
00DB1470  lea         edx,[ (0DB149Ch)]  
00DB1476  call        @ILT+120(@_RTC_CheckStackVars@8) (0DB107Dh)  
00DB147B  pop         eax  
00DB147C  pop         edx  
00DB147D  pop         edi  
00DB147E  pop         esi  
00DB147F  pop         ebx  
00DB1480  mov         ecx,dword ptr [ebp-4]  
00DB1483  xor         ecx,ebp  
00DB1485  call        @ILT+15(@__security_check_cookie@4) (0DB1014h)  
00DB148A  add         esp,158h  
00DB1490  cmp         ebp,esp  
00DB1492  call        @ILT+295(__RTC_CheckEsp) (0DB112Ch)  
00DB1497  mov         esp,ebp  
00DB1499  pop         ebp  
00DB149A  ret  
00DB149B  nop  
00DB149C  db          05h  
00DB149D  db          00h  
00DB149E  db          00h  
00DB149F  db          00h  
00DB14A0  db          a4h  
00DB14A1  db          14h  
00DB14A2  db          dbh  
00DB14A3  db          00h  
00DB14A4  db          e4h  
00DB14A5  db          ffh  
00DB14A6  db          ffh  
00DB14A7  db          ffh  
00DB14A8  db          14h  
00DB14A9  db          00h  
00DB14AA  db          00h  
00DB14AB  db          00h  
00DB14AC  db          e8h  
00DB14AD  db          14h  
00DB14AE  db          dbh  
00DB14AF  db          00h  
00DB14B0  db          c8h  
00DB14B1  db          ffh  
00DB14B2  db          ffh  
00DB14B3  db          ffh  
00DB14B4  db          14h  
00DB14B5  db          00h  
00DB14B6  db          00h  
00DB14B7  db          00h  
00DB14B8  db          e6h  
00DB14B9  db          14h  
00DB14BA  db          dbh  
00DB14BB  db          00h  
00DB14BC  db          ach  
00DB14BD  db          ffh  
00DB14BE  db          ffh  
00DB14BF  db          ffh  
00DB14C0  db          14h  
00DB14C1  db          00h  
00DB14C2  db          00h  
00DB14C3  db          00h  
00DB14C4  db          e4h  
00DB14C5  db          14h  
00DB14C6  db          dbh  
00DB14C7  db          00h  
00DB14C8  db          90h  
00DB14C9  db          ffh  
00DB14CA  db          ffh  
00DB14CB  db          ffh  
00DB14CC  db          14h  
00DB14CD  db          00h  
00DB14CE  db          00h  
00DB14CF  db          00h  
00DB14D0  db          e2h  
00DB14D1  db          14h  
00DB14D2  db          dbh  
00DB14D3  db          00h  
00DB14D4  db          78h  
00DB14D5  db          ffh  
00DB14D6  db          ffh  
00DB14D7  db          ffh  
00DB14D8  db          04h  
00DB14D9  db          00h  
00DB14DA  db          00h  
00DB14DB  db          00h  
00DB14DC  db          e0h  
00DB14DD  db          14h  
00DB14DE  db          dbh  
00DB14DF  db          00h  
00DB14E0  db          6bh  
00DB14E1  db          00h  
00DB14E2  db          64h  
00DB14E3  db          00h  
00DB14E4  db          63h  
00DB14E5  db          00h  
00DB14E6  db          62h  
00DB14E7  db          00h  
00DB14E8  db          61h  
00DB14E9  db          00h  
--- 无源文件 -----------------------------------------------------------------------
00DB14EA  int         3  
00DB14EB  int         3  
00DB14EC  int         3  
00DB14ED  int         3  
00DB14EE  int         3  
00DB14EF  int         3  
00DB14F0  int         3  
00DB14F1  int         3  
00DB14F2  int         3  
00DB14F3  int         3  
00DB14F4  int         3  
00DB14F5  int         3  
00DB14F6  int         3  
00DB14F7  int         3  
00DB14F8  int         3  
00DB14F9  int         3  
00DB14FA  int         3  
00DB14FB  int         3  
00DB14FC  int         3  
00DB14FD  int         3  
00DB14FE  int         3  
00DB14FF  int         3  
00DB1500  int         3  
00DB1501  int         3  
00DB1502  int         3  
00DB1503  int         3  
00DB1504  int         3  
00DB1505  int         3  
00DB1506  int         3  
00DB1507  int         3  
00DB1508  int         3  
00DB1509  int         3  
00DB150A  int         3  
00DB150B  int         3  
00DB150C  int         3  
00DB150D  int         3  
00DB150E  int         3  
00DB150F  int         3  
00DB1510  int         3  
00DB1511  int         3  
00DB1512  int         3  
00DB1513  int         3  
00DB1514  int         3  
00DB1515  int         3  
00DB1516  int         3  
00DB1517  int         3  
00DB1518  int         3  
00DB1519  int         3  
00DB151A  int         3  
00DB151B  int         3  
00DB151C  int         3  
00DB151D  int         3  
00DB151E  int         3  
00DB151F  int         3  
00DB1520  int         3  
00DB1521  int         3  
00DB1522  int         3  
00DB1523  int         3  
00DB1524  int         3  
00DB1525  int         3  
00DB1526  int         3  
00DB1527  int         3  
00DB1528  int         3  
00DB1529  int         3  
00DB152A  int         3  
00DB152B  int         3  
00DB152C  int         3  
00DB152D  int         3  
00DB152E  int         3  
00DB152F  int         3  
00DB1530  int         3  
00DB1531  int         3  
00DB1532  int         3  
00DB1533  int         3  
00DB1534  int         3  
00DB1535  int         3  
00DB1536  int         3  
00DB1537  int         3  
00DB1538  int         3  
00DB1539  int         3  
00DB153A  int         3  
00DB153B  int         3  
00DB153C  int         3  
00DB153D  int         3  
00DB153E  int         3  
00DB153F  int         3  

 

#29


接着

--- d:\documents\visual studio 2010\projects\调试5\调试5\调试5.cpp -------------------
    19: 
    20: int bigplus(unsigned char a[],unsigned char b[],unsigned char c[])  //大整数加法
    21: {
00DB1540  push        ebp  
00DB1541  mov         ebp,esp  
00DB1543  sub         esp,0DCh  
00DB1549  push        ebx  
00DB154A  push        esi  
00DB154B  push        edi  
00DB154C  lea         edi,[ebp-0DCh]  
00DB1552  mov         ecx,37h  
00DB1557  mov         eax,0CCCCCCCCh  
00DB155C  rep stos    dword ptr es:[edi]  
    22:     int i,len;
    23:     len=(a[0]>b[0]?a[0]:b[0]);  //a[0] b[0]保存数组长度,len为较长的一个
00DB155E  mov         eax,dword ptr [a]  
00DB1561  movzx       ecx,byte ptr [eax]  
00DB1564  mov         edx,dword ptr [b]  
00DB1567  movzx       eax,byte ptr [edx]  
00DB156A  cmp         ecx,eax  
00DB156C  jle         bigplus+3Bh (0DB157Bh)  
00DB156E  mov         ecx,dword ptr [a]  
00DB1571  mov         dl,byte ptr [ecx]  
00DB1573  mov         byte ptr [ebp-0D9h],dl  
00DB1579  jmp         bigplus+46h (0DB1586h)  
00DB157B  mov         eax,dword ptr [b]  
00DB157E  mov         cl,byte ptr [eax]  
00DB1580  mov         byte ptr [ebp-0D9h],cl  
00DB1586  movzx       edx,byte ptr [ebp-0D9h]  
00DB158D  mov         dword ptr [len],edx  
    24:     for(i=0;i<MAXINT;i++)       //将数组清0
00DB1590  mov         dword ptr [i],0  
00DB1597  jmp         bigplus+62h (0DB15A2h)  
00DB1599  mov         eax,dword ptr [i]  
00DB159C  add         eax,1  
00DB159F  mov         dword ptr [i],eax  
00DB15A2  cmp         dword ptr [i],14h  
00DB15A6  jge         bigplus+73h (0DB15B3h)  
    25:         c[i]=0;
00DB15A8  mov         eax,dword ptr [c]  
00DB15AB  add         eax,dword ptr [i]  
00DB15AE  mov         byte ptr [eax],0  
00DB15B1  jmp         bigplus+59h (0DB1599h)  
    26:     for (i=1;i<=len;i++)        //计算每一位的值
00DB15B3  mov         dword ptr [i],1  
00DB15BA  jmp         bigplus+85h (0DB15C5h)  
00DB15BC  mov         eax,dword ptr [i]  
00DB15BF  add         eax,1  
00DB15C2  mov         dword ptr [i],eax  
00DB15C5  mov         eax,dword ptr [i]  
00DB15C8  cmp         eax,dword ptr [len]  
00DB15CB  jg          bigplus+0EDh (0DB162Dh)  
    27:     {
    28:         c[i]+=(a[i]+b[i]);
00DB15CD  mov         eax,dword ptr [a]  
00DB15D0  add         eax,dword ptr [i]  
00DB15D3  movzx       ecx,byte ptr [eax]  
00DB15D6  mov         edx,dword ptr [b]  
00DB15D9  add         edx,dword ptr [i]  
00DB15DC  movzx       eax,byte ptr [edx]  
00DB15DF  add         ecx,eax  
00DB15E1  mov         edx,dword ptr [c]  
00DB15E4  add         edx,dword ptr [i]  
00DB15E7  movzx       eax,byte ptr [edx]  
00DB15EA  add         eax,ecx  
00DB15EC  mov         ecx,dword ptr [c]  
00DB15EF  add         ecx,dword ptr [i]  
00DB15F2  mov         byte ptr [ecx],al  
    29:         if (c[i]>=10)
00DB15F4  mov         eax,dword ptr [c]  
00DB15F7  add         eax,dword ptr [i]  
00DB15FA  movzx       ecx,byte ptr [eax]  
00DB15FD  cmp         ecx,0Ah  
00DB1600  jl          bigplus+0EBh (0DB162Bh)  
    30:         {
    31:            c[i]-=10;            //大于10的取个位
00DB1602  mov         eax,dword ptr [c]  
00DB1605  add         eax,dword ptr [i]  
00DB1608  movzx       ecx,byte ptr [eax]  
00DB160B  sub         ecx,0Ah  
00DB160E  mov         edx,dword ptr [c]  
00DB1611  add         edx,dword ptr [i]  
00DB1614  mov         byte ptr [edx],cl  
    32:            c[i+1]++;            //高位加1
00DB1616  mov         eax,dword ptr [c]  
00DB1619  add         eax,dword ptr [i]  
00DB161C  mov         cl,byte ptr [eax+1]  
00DB161F  add         cl,1  
00DB1622  mov         edx,dword ptr [c]  
00DB1625  add         edx,dword ptr [i]  
00DB1628  mov         byte ptr [edx+1],cl  
    33:         }
    34:     }
00DB162B  jmp         bigplus+7Ch (0DB15BCh)  
    35:     if (c[i+1]>0) len++;
00DB162D  mov         eax,dword ptr [c]  
00DB1630  add         eax,dword ptr [i]  
00DB1633  movzx       ecx,byte ptr [eax+1]  
00DB1637  test        ecx,ecx  
00DB1639  jle         bigplus+104h (0DB1644h)  
00DB163B  mov         eax,dword ptr [len]  
00DB163E  add         eax,1  
00DB1641  mov         dword ptr [len],eax  
    36:         c[0]=len;                //c[0]保存结果数组实际长度
00DB1644  mov         eax,dword ptr [c]  
00DB1647  mov         cl,byte ptr [len]  
00DB164A  mov         byte ptr [eax],cl  
    37:     printf("Big integers add: ");
00DB164C  mov         esi,esp  
00DB164E  push        offset string "Big integers add: " (0DB5744h)  
00DB1653  call        dword ptr [__imp__printf (0DB82B4h)]  
00DB1659  add         esp,4  
00DB165C  cmp         esi,esp  
00DB165E  call        @ILT+295(__RTC_CheckEsp) (0DB112Ch)  
    38:     for (i=len;i>=1;i--)
00DB1663  mov         eax,dword ptr [len]  
00DB1666  mov         dword ptr [i],eax  
00DB1669  jmp         bigplus+134h (0DB1674h)  
00DB166B  mov         eax,dword ptr [i]  
00DB166E  sub         eax,1  
00DB1671  mov         dword ptr [i],eax  
00DB1674  cmp         dword ptr [i],1  
00DB1678  jl          bigplus+15Dh (0DB169Dh)  
    39:                 printf("%d",c[i]); //打印结果
00DB167A  mov         eax,dword ptr [c]  
00DB167D  add         eax,dword ptr [i]  
00DB1680  movzx       ecx,byte ptr [eax]  
00DB1683  mov         esi,esp  
00DB1685  push        ecx  
00DB1686  push        offset string "%d" (0DB5740h)  
00DB168B  call        dword ptr [__imp__printf (0DB82B4h)]  
00DB1691  add         esp,8  
00DB1694  cmp         esi,esp  
00DB1696  call        @ILT+295(__RTC_CheckEsp) (0DB112Ch)  
00DB169B  jmp         bigplus+12Bh (0DB166Bh)  
    40:         printf("\n");
00DB169D  mov         esi,esp  
00DB169F  push        offset string "\n" (0DB573Ch)  
00DB16A4  call        dword ptr [__imp__printf (0DB82B4h)]  
00DB16AA  add         esp,4  
00DB16AD  cmp         esi,esp  
00DB16AF  call        @ILT+295(__RTC_CheckEsp) (0DB112Ch)  
    41:     return 0;
00DB16B4  xor         eax,eax  
    42: }
00DB16B6  pop         edi  
00DB16B7  pop         esi  
00DB16B8  pop         ebx  
00DB16B9  add         esp,0DCh  
00DB16BF  cmp         ebp,esp  
00DB16C1  call        @ILT+295(__RTC_CheckEsp) (0DB112Ch)  
00DB16C6  mov         esp,ebp  
00DB16C8  pop         ebp  
00DB16C9  ret  

#30


代码功能归根结底不是别人帮自己看或讲解或注释出来的;而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。
提醒:再牛×的老师也无法代替学生自己领悟和上厕所!
单步调试和设断点调试(VS IDE中编译连接通过以后,按F10或F11键单步执行,按Shift+F11退出当前函数;在某行按F9设断点后按F5执行停在该断点处。)是程序员必须掌握的技能之一。

#31


最后是我嵌入C语言的代码。
#include<stdio.h>
# define MAXINT 20
int bigplus(unsigned char a[],unsigned char b[],unsigned char c[]);
int main(int argc, char *argv[])
{
unsigned char a[MAXINT]={10,0,9,8,7,6,5,4,3,2,1};
unsigned char b[MAXINT]={8,8,7,6,5,4,3,2,1};
unsigned char c[MAXINT],d[MAXINT];                    //c[]存放商,d[]存放余数,g[]是除法时每次相乘的结果

 bigplus(a,b,c);
 return 0;
}
 
int bigplus(unsigned char a[],unsigned char b[],unsigned char c[])
{
 int i,len;
    len=(a[0]>b[0]?a[0]:b[0]);  //a[0] b[0]保存数组长度,len为较长的一个
printf("len=%d\n",len);
for(i=0;i<MAXINT;i++)       //将数组清0
{  
c[i]=0;
}
__asm
{
mov         dword ptr [i],1  
jmp         dian
}

dian:
__asm
{
        mov         eax,dword ptr [i]  
cmp         eax,dword ptr [len]  
jg          dian2
//c[i]+=(a[i]+b[i]);
mov         eax,dword ptr [a]  
add         eax,dword ptr [i]  
movzx       ecx,byte ptr [eax]  
mov         edx,dword ptr [b]  
add         edx,dword ptr [i]  
movzx       eax,byte ptr [edx]  
add         ecx,eax  
mov         edx,dword ptr [c]  
add         edx,dword ptr [i]  
    movzx       eax,byte ptr [edx]  
add         eax,ecx  
mov         ecx,dword ptr [c]  
add         ecx,dword ptr [i]  
mov         byte ptr [ecx],al  
//       if (c[i]>=10)
    mov         eax,dword ptr [c]  
add         eax,dword ptr [i]  
movzx       ecx,byte ptr [eax]  
cmp         ecx,0Ah  
jl          dian3       //小于10,跳转到开始循环位置
   // c[i]-=10;            //大于10的取个位
mov         eax,dword ptr [c]  
add         eax,dword ptr [i]  
        movzx       ecx,byte ptr [eax]  
        sub         ecx,0Ah  
        mov         edx,dword ptr [c]  
        add         edx,dword ptr [i]  
        mov         byte ptr [edx],cl  
//        c[i+1]++;            //高位加1
mov         eax,dword ptr [c]  
        add         eax,dword ptr [i]  
        mov         cl,byte ptr [eax+1]  
        add         cl,1  
        mov         edx,dword ptr [c]  
        add         edx,dword ptr [i]  
        mov         byte ptr [edx+1],cl  
// jmp         bigplus+7Ch (13315BCh)  
}
dian3:
__asm
{
      mov         eax,dword ptr [i]  
add         eax,1  
mov         dword ptr [i],eax  
        mov         eax,dword ptr [i]  
cmp         eax,dword ptr [len]  
jg          dian2
//c[i]+=(a[i]+b[i]);
mov         eax,dword ptr [a]  
add         eax,dword ptr [i]  
movzx       ecx,byte ptr [eax]  
mov         edx,dword ptr [b]  
add         edx,dword ptr [i]  
movzx       eax,byte ptr [edx]  
add         ecx,eax  
mov         edx,dword ptr [c]  
add         edx,dword ptr [i]  
    movzx       eax,byte ptr [edx]  
add         eax,ecx  
mov         ecx,dword ptr [c]  
add         ecx,dword ptr [i]  
mov         byte ptr [ecx],al    
 //       if (c[i]>=10)
    mov         eax,dword ptr [c]  
add         eax,dword ptr [i]  
movzx       ecx,byte ptr [eax]  
cmp         ecx,0Ah  
jl          dian3
//  jl          bg  //小于10,跳转到开始循环位置
   // c[i]-=10;            //大于10的取个位
mov         eax,dword ptr [c]  
add         eax,dword ptr [i]  
        movzx       ecx,byte ptr [eax]  
        sub         ecx,0Ah  
        mov         edx,dword ptr [c]  
        add         edx,dword ptr [i]  
        mov         byte ptr [edx],cl  
   //        c[i+1]++;            //高位加1
mov         eax,dword ptr [c]  
        add         eax,dword ptr [i]  
        mov         cl,byte ptr [eax+1]  
        add         cl,1  
        mov         edx,dword ptr [c]  
        add         edx,dword ptr [i]  
        mov         byte ptr [edx+1],cl  
// jmp         bigplus+7Ch (13315BCh)  
}
dian2:
__asm
{
mov         eax,dword ptr [c]  
        add         eax,dword ptr [i]  
        movzx       ecx,byte ptr [eax+1]  
        test        ecx,ecx  
        jle         dian4
        mov         eax,dword ptr [len]  
        add         eax,1  
        mov         dword ptr [len],eax  
jmp        dian4
}
   //    c[0]=len;                //c[0]保存结果数组实际长度

dian4:  
__asm
{
mov         eax,dword ptr [c]  
        mov         cl,byte ptr [len]  
        mov         byte ptr [eax],cl  
}
printf("Big integers add: ");
// printf("10进制:");
    for (i=len;i>=1;i--)
{
                printf("%d,",c[i]); //打印结果

}
        printf("\n");
return 0;
}



因为原始的的反汇编代码,要跳转,而且跳转的位置还是直接用地址表示的。而我在编写的时候无法知道地址信息。所以一开始我是把相应的地址对应的行给标上一个名字,比如jmp     jisuan。然后我把某一行前面标上jisuan:,然而,运行的结果是,貌似电脑无法识别这种标识。当然了,我记得在编写纯粹的汇编语言代码时是可以的,但是也许在C语言中是无法识别的。当然,没有报错,只是结果不对。

然后我把对应的跳转程序,分成一个个的小段,从这段跳转到另一段。结果是,程序不报错,但是结果不对。只有个位和十位正确,从百位开始就错了。往后更是都变成了0。
如果您忙的话,不用仔细看程序,跟我说说我是不是引用的格式(或者方式)不对啊。

#32


试试:
项目、属性、配置属性、C/C++、输出文件、汇编程序输出:程序集、机器码和源代码(/Facs)
在重新编译,查看生成的.asm文件内容。
如何把汇编程序嵌入到C语言中

#33


再重新编译

#34


引用 30 楼 zhao4zhong1 的回复:
代码功能归根结底不是别人帮自己看或讲解或注释出来的;而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。
提醒:再牛×的老师也无法代替学生自己领悟和上厕所!
单步调试和设断点调试(VS IDE中编译连接通过以后,按F10或F11键单步执行,按Shift+F11退出当前函数;在某行按F9设断点后按F5执行停在该断点处。)是程序员必须掌握的技能之一。
我按F10或者F11,逐过程或者逐语句的调试,但是在main()函数里运行到子函数的时候,跳入子函数,然后再按往下走的时候,马上他就又进行反汇编了。紧接着就在不同的文件中调用,跳转,最后退出。总之没有在我的子函数中继续往下走。是不是说明我的子函数有逻辑上的问题啊。

#35


VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。

#36


哈哈哈哈,嵌入成功了。感谢赵老师@赵4老师 ,感谢楼上各位的帮助。谢谢大家!!!!

#37


引用 36 楼 chimenghuanzhe 的回复:
哈哈哈哈,嵌入成功了。感谢赵老师@赵4老师 ,感谢楼上各位的帮助。谢谢大家!!!!

如何把汇编程序嵌入到C语言中小确幸!

#38


引用 36 楼 chimenghuanzhe 的回复:
哈哈哈哈,嵌入成功了。感谢赵老师@赵4老师 ,感谢楼上各位的帮助。谢谢大家!!!!
虽说老师交给我的任务离完成还遥遥无期,但是毕竟是迈出了第一步。接下来我只要把C语言编好的加减乘除都转化成汇编语言,就已经完成了10%。然后再完成cos函数的运算,这就完成了60%。最后用龙格库塔算法把微分积分方程的数值解求出来就算完成了90%,最后把结果写入txt文件中就是真正的完成了。

一开始接手这个任务时,我信心满满,可是当自己着手开始做的时候,才发现,对于一个512位的数据,我怎么表示,这就成了第一大难关,如果不解决了,接下来的计算就无法进行。之后我试着位运算来计算加减乘除,可是,却不知道减法和乘法如何实现,更别提除法了。于是只好用C语言的算术运算来解决。被老师狠狠地批了一顿,并要求我必须用汇编或者位运算来完成计算过程。从此接近5天了,终于把汇编嵌入到了C语言中。虽然对开学之前完成整个工作抱有悲观看法,但是还是要继续努力做下去。总之要把它完成。

#39


老师也有老师对的地方和难处。 如何把汇编程序嵌入到C语言中

#40


引用 39 楼 zhao4zhong1 的回复:
老师也有老师对的地方和难处。 如何把汇编程序嵌入到C语言中
嗯哪嗯哪,我理解。

#41


恭喜,蹭点分

#42


引用 41 楼 Dobzhansky 的回复:
恭喜,蹭点分

欢迎欢迎 如何把汇编程序嵌入到C语言中

#43


你只是源码级别的嵌入,我们可以考虑目标文件级别的嵌入。即汇编代码用汇编程序编译成目标文件,C语言代码用C编译器编译成目标文件,然后利用连接器链接这两个目标文件。