나는 어셈블러를 배우고있다. 이 코드 연습 :실행 대 디버그 = 어셈블러에서 다른 결과
ASM :
;-------------------------------------------------------------------------
.586
.MODEL flat, stdcall
public srednia_harm
OPTION CASEMAP:NONE
INCLUDE include\windows.inc
INCLUDE include\user32.inc
INCLUDE include\kernel32.inc
.CODE
jeden dd 1.0
DllEntry PROC hInstDLL:HINSTANCE, reason:DWORD, reserved1:DWORD
mov eax, TRUE
ret
DllEntry ENDP
;-------------------------------------------------------------------------
;-------------------------------------------------------------------------
srednia_harm PROC
push ebp
mov esp,ebp
push esi
mov esi, [ebp+8] ; address of array
mov ecx, [ebp+12] ; the number of elements
finit
fldz ; the current value of the sum - st(0)=0
mianownik:
fld dword PTR jeden ;ST(0)=1, ST(1)=sum
fld dword PTR [esi] ;loading of array elements - ST(0)=tab[i], ST(1)=1 ST(2)=suma
fdivp st(1), st(0) ; st(1)=st(1)/(st0) -> ST(0)=1/tab[i], ST(1)=suma
faddp st(1),st(0) ; st(1)=st(0)+st(1) -> st(0)=suma+1/tab[i]
add esi,4
loop mianownik
pop esi
pop ebp
ret
srednia_harm ENDP
;-------------------------------------------------------------------------
;-------------------------------------------------------------------------
;-------------------------------------------------------------------------
;-------------------------------------------------------------------------
;-------------------------------------------------------------------------
;-------------------------------------------------------------------------
END DllEntry
DEF :
LIBRARY "biblioteka"
EXPORTS
srednia_harm
C 번호 :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
namespace GUI
{
unsafe class FunkcjeAsemblera //imports of assembler's function
{
[DllImport("bibliotekaASM.dll", CallingConvention = CallingConvention.StdCall)]
private static extern float srednia_harm(float[] table, int n);
public float wywolajTest(float[] table, int n)
{
float wynik = srednia_harm(table, n);
return wynik;
}
}
}
C 번호 : 나는이 코드를 실행하면
private void button6_Click(object sender, EventArgs e)
{
FunkcjeAsemblera funkcje = new FunkcjeAsemblera();
int n = 4;
float[] table = new float[n];
for (int i = 0; i < n; i++)
table[i] = 1;
float wynik = funkcje.wywolajTest(table, n);
textBox6.Text = wynik.ToString();
}
모든 것이 괜찮습니다. 결과는 내가 예상 한대로 4입니다. 하지만 그 코드를 이해하려고 했으므로 ASM 기능에 많은 중단 점을 설정했습니다. 그런 다음 문제가 시작되었습니다. Arrat은 정확하게 기억에 있어야하지만 seond 매개 변수는 손실됩니다. 주소가 메모리의 빈 필드를 가리 킵니다. 나는 많은 조합을 시도했다, 나는 개미를 바꿨다. 그것은 아직도 같았다. 몇 가지 조사를했지만 단서를 찾지 못했습니다. 어떻게하면 프로그램을 실행할 때 모든 것이 잘 작동하고 DEBUG에서는 불가능할 수 있습니까?
디버그 및 릴리스의 컴파일러 출력이 다릅니다. 디버그 버전은 최적화가 해제 된 상태에서 컴파일되고 릴리스에는 최적화가 설정된 상태로 컴파일됩니다. 그들은 다른 기계 코드를 산출 할 다른 MSIL을 산출 할 것이다. –
"하지만 seond 매개 변수가 손실됩니다." 언더 레이 변수가 다른 값을 갖고 있다고 말하는가? 디버그 빌드는 모든 변수를 0으로 강제하는 경향이있는 반면, 릴리스에서는 중복되는 경우이를 최적화 할 수 있습니다. –
StdCall이라고 표시했지만 그 내용은 귀하가 작성한 내용이 아닙니다. 이 문제를 해결하려면 C 컴파일러를 사용하십시오. 또는 StdCall이 의미하는 바를 이해할 수 있도록 생성하는 어셈블리를 살펴보십시오. –