I want to know the corresponding c code of the following asm code, and if you can a explanation of the asm code
PUBLIC fonction2
_tab DW 0aH DUP (?)
_idx$ = 8 ; size =4
_value$ = 12 ; size =2
fonction2 PROC
push ebp
mov ebp, esp
mov eax, DWORD PTR _idx$[ebp]
mov cx, WORD PTR _value$[ebp]
mov word PTR _tab[eax*2], cx
pop ebp
ret 0
fonction2 ENDP
What's _idx$ and _value$.
Thanks for your help in advance.
void fonction2 (int idx, short value)
{
tab [idx] = value;
}
Related
I'm running into the following error for my _asm code in Visual Studio:
"First-chance exception at 0x00431BCF in HW7.exe: 0xC0000005: Access violation writing location 0x00000000."
#include <stdio.h>
#include <stddef.h>
// Function to implement strncpy() function
char* strncpy(char* destination, const char* source, size_t num)
{
_asm {
push ebp
mov ebp, esp
sub esp, 208; 000000d0H
push ebx
push esi
push edi
lea edi, DWORD PTR[ebp - 208]
mov ecx, 52; 00000034H
mov eax, -858993460; ccccccccH
rep stosd
cmp DWORD PTR[destination], 0
jne label_3
xor eax, eax
jmp label_4
label_3:
mov eax, DWORD PTR[destination]
mov DWORD PTR[ebp-08h], eax
label_2:
mov eax, DWORD PTR[source]
movsx ecx, BYTE PTR[eax]
test ecx, ecx
je label_1
mov eax, DWORD PTR[num]
mov DWORD PTR[ebp-0D0h], eax
mov ecx, DWORD PTR[num]
sub ecx, 1
mov DWORD PTR[num], ecx
cmp DWORD PTR[ebp-0D0h], 0
je label_1
mov eax, DWORD PTR[destination]
mov ecx, DWORD PTR[source]
mov dl, BYTE PTR[ecx]
mov BYTE PTR[eax], dl
mov eax, DWORD PTR[destination]
add eax, 1
mov DWORD PTR[destination], eax
mov eax, DWORD PTR[source]
add eax, 1
mov DWORD PTR[source], eax
jmp label_2
label_1:
mov eax, DWORD PTR[destination]
mov BYTE PTR[eax], 0
mov eax, DWORD PTR[ebp-08h]
label_4:
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret 0
}
/*
// return if no memory is allocated to the destination
if (destination == NULL)
return NULL;
// take a pointer pointing to the beginning of destination string
char* ptr = destination;
// copy first num characters of C-string pointed by source
// into the array pointed by destination
while (*source && num--)
{
*destination = *source;
destination++;
source++;
}
// null terminate destination string
*destination = '\0';
// destination is returned by standard strncpy()
return ptr;
*/
}
// Implement strncpy() function in C
int main(void)
{
/*
char* source = "Crisp Rat";
char destination[12];
*/
/*
char* source = "Christians Later";
char destination[12];
*/
char* source = "Huge Ackman";
char destination[12];
size_t num = 11;
// Copies the first num characters of source to destination
printf("%s\n", strncpy(destination, source, num));
return 0;
}
I've stepped through the code and the error occurs at the instruction "mov byte ptr[eax],dl".
My C code equivalent of the asm code is commented out just below it. I appreciate any help very much, thank you.
I wrote this classic function : (in 32-bit mode)
void ex(size_t a, size_t b)
{
size_t c;
c = a;
a = b;
b = c;
}
I call it inside the main as follows :
size_t a = 4;
size_t b = 5;
ex(a,b);
What I was expecting from the assembly code generated when entering the function is something like this :
1-Push the values of b and a in the stack : (which was done)
mov eax,dword ptr [b]
push eax
mov ecx,dword ptr [a]
push ecx
2-Use the values of a and b in the stack :
push ebp
mov ebp, esp
sub esp, 4
c = a;
mov eax, dword ptr [ebp+8]
mov dword ptr [ebp-4], eax
and so on for the other variables.
However, this is what I find when debugging :
push ebp
mov ebp,esp
sub esp,0CCh // normal since it's in debug with ZI option
push ebx
push esi
push edi
lea edi,[ebp-0CCh]
mov ecx,33h
mov eax,0CCCCCCCCh
rep stos dword ptr es:[edi]
size_t c;
c = a;
mov eax,dword ptr [a]
mov dword ptr [c],eax
Why is it using the variable a directly instead of calling the value stored in the stack? I don't understand...
The debugger doesn't show the instruction using ebp to access a. The same syntax is permitted when you write inline assembly. Otherwise the reason that dword ptr still appears.
It is easy to get it your preferred way, right click > untick "Show Symbol Names".
Using the assembly output option (right click on file name, properties, ...), I get what you expect from debug assembly output. This could depend on which version of VS you use. For this example, I used VS2005. I have VS2015 on a different system, but didn't try it yet.
_c$ = -8 ; size = 4
_a$ = 8 ; size = 4
_b$ = 12 ; size = 4
_ex PROC ; COMDAT
push ebp
mov ebp, esp
sub esp, 204 ; 000000ccH
push ebx
push esi
push edi
lea edi, DWORD PTR [ebp-204]
mov ecx, 51 ; 00000033H
mov eax, -858993460 ; ccccccccH
rep stosd ;fill with 0cccccccch
mov eax, DWORD PTR _a$[ebp]
mov DWORD PTR _c$[ebp], eax
mov eax, DWORD PTR _b$[ebp]
mov DWORD PTR _a$[ebp], eax
mov eax, DWORD PTR _c$[ebp]
mov DWORD PTR _b$[ebp], eax
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret 0
_ex ENDP
Note this doesn't work, you need to use pointers for the swap to work.
void ex(size_t *pa, size_t *pb)
{
size_t c;
c = *pa;
*pa = *pb;
*pb = c;
}
which gets translated into:
_c$ = -8 ; size = 4
_pa$ = 8 ; size = 4
_pb$ = 12 ; size = 4
_ex PROC ; COMDAT
push ebp
mov ebp, esp
sub esp, 204 ; 000000ccH
push ebx
push esi
push edi
lea edi, DWORD PTR [ebp-204]
mov ecx, 51 ; 00000033H
mov eax, -858993460 ; ccccccccH
rep stosd
mov eax, DWORD PTR _pa$[ebp]
mov ecx, DWORD PTR [eax]
mov DWORD PTR _c$[ebp], ecx
mov eax, DWORD PTR _pa$[ebp]
mov ecx, DWORD PTR _pb$[ebp]
mov edx, DWORD PTR [ecx]
mov DWORD PTR [eax], edx
mov eax, DWORD PTR _pb$[ebp]
mov ecx, DWORD PTR _c$[ebp]
mov DWORD PTR [eax], ecx
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret 0
_ex ENDP
I'm trying to link main.c program with procedure.asm. I have the following C program and Assembly program.
main.c
#include <Windows.h>
#include <iostream>
using namespace std;
extern "C" {
void ClearUsingIndex(int[], int);
}
static int Array[10] ={1, 2, 3, 4, 5, 6, 7, 8, 9, -1};
int main()
{
int size = 10;
ClearUsingIndex( Array, size);
system("pause");
return 0;
}
procedure.asm
; Listing generated by Microsoft (R) Optimizing Compiler Version 17.00.50727.1
TITLE c:\Users\GS\documents\visual studio 2012\Projects\ClearIndex\ClearIndex\procedure.cpp
.686P
.XMM
include listing.inc
.model flat
INCLUDELIB MSVCRTD
INCLUDELIB OLDNAMES
PUBLIC ?ClearUsingIndex##YAXQAHH#Z ; ClearUsingIndex
EXTRN __RTC_InitBase:PROC
EXTRN __RTC_Shutdown:PROC
; COMDAT rtc$TMZ
rtc$TMZ SEGMENT
__RTC_Shutdown.rtc$TMZ DD FLAT:__RTC_Shutdown
rtc$TMZ ENDS
; COMDAT rtc$IMZ
rtc$IMZ SEGMENT
__RTC_InitBase.rtc$IMZ DD FLAT:__RTC_InitBase
rtc$IMZ ENDS
; Function compile flags: /Odtp /RTCsu /ZI
; COMDAT ?ClearUsingIndex##YAXQAHH#Z
_TEXT SEGMENT
_i$ = -8 ; size = 4
_Array$ = 8 ; size = 4
_size$ = 12 ; size = 4
?ClearUsingIndex##YAXQAHH#Z PROC ; ClearUsingIndex, COMDAT
; File c:\users\gs\documents\visual studio 2012\projects\clearindex\clearindex\procedure.cpp
; Line 2
push ebp
mov ebp, esp
sub esp, 204 ; 000000ccH
push ebx
push esi
push edi
lea edi, DWORD PTR [ebp-204]
mov ecx, 51 ; 00000033H
mov eax, -858993460 ; ccccccccH
rep stosd
; Line 4
mov DWORD PTR _i$[ebp], 0
jmp SHORT $LN3#ClearUsing
$LN2#ClearUsing:
mov eax, DWORD PTR _i$[ebp]
add eax, 1
mov DWORD PTR _i$[ebp], eax
$LN3#ClearUsing:
mov eax, DWORD PTR _i$[ebp]
cmp eax, DWORD PTR _size$[ebp]
jge SHORT $LN4#ClearUsing
; Line 5
mov eax, DWORD PTR _i$[ebp]
mov ecx, DWORD PTR _Array$[ebp]
mov DWORD PTR [ecx+eax*4], 0
jmp SHORT $LN2#ClearUsing
$LN4#ClearUsing:
; Line 6
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret 0
?ClearUsingIndex##YAXQAHH#Z ENDP ; ClearUsingIndex
_TEXT ENDS
END
I did some research and I found the following source and followed the instructions: Guide to Using Assembly in Visual Studio .NET
But I get the following error when I compile the assembly file.
error A1017: missing source filename
I google the error but all the methods I tried don't seem to work.
I am finishing up an assembly program that replaces characters in a string with a given replacement character. The assembly code calls C functions and the assembly program itself is called from main in my .c file. However, when trying to finish and return a final int value FROM the assembly program TO C, I get segfaults. My .asm file is as follows:
; File: strrepl.asm
; Implements a C function with the prototype:
;
; int strrepl(char *str, int c, int (* isinsubset) (int c) ) ;
;
;
; Result: chars in string are replaced with the replacement character and string is returned.
SECTION .text
global strrepl
_strrepl: nop
strrepl:
push ebp ; set up stack frame
mov ebp, esp
push esi ; save registers
push ebx
xor eax, eax
mov ecx, [ebp + 8] ;load string (char array) into ecx
jecxz end ;jump if [ecx] is zero
mov al, [ebp + 12] ;move the replacement character into esi
mov edx, [ebp + 16] ;move function pointer into edx
firstLoop:
xor eax, eax
mov edi, [ecx]
cmp edi, 0
jz end
mov edi, ecx ; save array
movzx eax, byte [ecx] ;load single byte into eax
push eax ; parameter for (*isinsubset)
mov edx, [ebp + 16]
call edx ; execute (*isinsubset)
mov ecx, edi ; restore array
cmp eax, 0
jne secondLoop
add esp, 4 ; "pop off" the parameter
mov ebx, eax ; store return value
add ecx, 1
jmp firstLoop
secondLoop:
mov eax, [ebp+12]
mov [ecx], al
mov edx, [ebp+16]
add esp, 4
mov ebx, eax
add ecx, 1
jmp firstLoop
end:
pop ebx ; restore registers
pop esi
mov esp, ebp ; take down stack frame
pop ebp
mov eax, 9
push eax ;test
ret
and my c file is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
//display *((char *) $edi)
// These functions will be implemented in assembly:
//
int strrepl(char *str, int c, int (* isinsubset) (int c) ) ;
int isvowel (int c) {
if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u')
return 1 ;
if (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U')
return 1 ;
return 0 ;
}
int main(){
char *str1;
int r;
str1 = strdup("ABC 123 779 Hello World") ;
r = strrepl(str1, '#', &isdigit) ;
printf("str1 = \"%s\"\n", str1) ;
printf("%d chararcters were replaced\n", r) ;
free(str1) ;
return 0;
}
In my assembly code, you can see in end
mov eax, 9
push eax
I am simply trying to return the value 9 to the value "r" which is an int in the C file. This is just a test to see if I can return an int back to r in the c file. Eventually I will be returning the number of characters that were replaced back to r. However, I need to figure out why the following code above is segfaulting. Any ideas?
mov eax, 9
push eax ; NOT a good idea
ret
That is a big mistake. It's going to return based on the lowest thing on the stack and you've just pushed something on to the stack that's almost certainly not a valid return address.
Most functions return a code by simply placing it into eax (this depends on calling convention of course but that's a pretty common one), there's generally no need to push it on to the stack, and certainly plenty of downside to doing so.
Return values are normally stored in EAX on X86 32 bit machines. So your pushing it on the stack after storing it in EAX is wrong, because the function it is returning to will try to use what is in EAX as a value for IP (instruction pointer)
Ret with no argument pops the return address off of the stack and jumps to it.
source
I'm stuck with this. I'm self studying assenbler and translating some basics instructions. But i can't with this one.
Can anyone help me, please?
int
secuencia ( int n, EXPRESION * * o )
{
int a, i;
for ( i = 0; i < n; i++ ){
a = evaluarExpresion( *o );
// Im trying to do this: o++;
__asm {
mov eax,dword ptr [o]
mov ecx,dword ptr [eax]
inc [ecx]
}
}
return a ;
}
I wrote the inside for and works, but still don't know how to increment O
int
secuencia ( int n, EXPRESION * * o )
{
int a, i;
for ( i = 0; i < n; i++ ){
__asm {
mov eax,dword ptr [o]
mov ecx,dword ptr [eax]
push ebp
mov ebp, esp
push ecx
call evaluarExpresion
mov esp, ebp
pop ebp
mov a, eax
}
o++;
}
return a ;
}
mov esi, o
add esi, 4 //increment is here
Line1 : We move your o pointer to the esi register.
Line2: We increment your o pointer
or
mov eax, o
mov esi, [eax]
add esi, 4
I don't understand perfectly what you are trying to do but I hope it helped!
There are two options:
Either:
move the value of o from memory into a register (eax, for example)
increment the register
move the value from the register back to memory
or
increment the value stored in memory directly
Try to use both methods.