Changing a variable whose address is in stack
so let's say this is my main
main PROC
sub esp, 4
push OFFSET variableName
call changeVariable
changeVariable PROC
push ebp
mov ebp, esp
How can I change variableName to a different value (say, 10) in the changeVariable procedure?
I tried
mov OFFSET[ebp+8], 10 ;ebp[+8] is the position in stack that holds address of variableName
but that doesn't work
assembly x86 masm irvine32
add a comment |
so let's say this is my main
main PROC
sub esp, 4
push OFFSET variableName
call changeVariable
changeVariable PROC
push ebp
mov ebp, esp
How can I change variableName to a different value (say, 10) in the changeVariable procedure?
I tried
mov OFFSET[ebp+8], 10 ;ebp[+8] is the position in stack that holds address of variableName
but that doesn't work
assembly x86 masm irvine32
1
You need another dereference. Load the address into a scratch register and then deref that.
– Peter Cordes
Nov 22 '18 at 2:39
add a comment |
so let's say this is my main
main PROC
sub esp, 4
push OFFSET variableName
call changeVariable
changeVariable PROC
push ebp
mov ebp, esp
How can I change variableName to a different value (say, 10) in the changeVariable procedure?
I tried
mov OFFSET[ebp+8], 10 ;ebp[+8] is the position in stack that holds address of variableName
but that doesn't work
assembly x86 masm irvine32
so let's say this is my main
main PROC
sub esp, 4
push OFFSET variableName
call changeVariable
changeVariable PROC
push ebp
mov ebp, esp
How can I change variableName to a different value (say, 10) in the changeVariable procedure?
I tried
mov OFFSET[ebp+8], 10 ;ebp[+8] is the position in stack that holds address of variableName
but that doesn't work
assembly x86 masm irvine32
assembly x86 masm irvine32
edited Nov 22 '18 at 2:39
Peter Cordes
122k17185312
122k17185312
asked Nov 22 '18 at 2:18
newbieProgrammernewbieProgrammer
43
43
1
You need another dereference. Load the address into a scratch register and then deref that.
– Peter Cordes
Nov 22 '18 at 2:39
add a comment |
1
You need another dereference. Load the address into a scratch register and then deref that.
– Peter Cordes
Nov 22 '18 at 2:39
1
1
You need another dereference. Load the address into a scratch register and then deref that.
– Peter Cordes
Nov 22 '18 at 2:39
You need another dereference. Load the address into a scratch register and then deref that.
– Peter Cordes
Nov 22 '18 at 2:39
add a comment |
2 Answers
2
active
oldest
votes
You are pushing a pointer, as noted in the comment you need to deference it.
Refer to this Godbolt example where this C code
void bar(int* c)
{
*c = 10;
}
void foo(int c)
{
c = 10;
}
int myVar;
int main()
{
bar(&myVar);
foo(myVar);
}
is assembled into
bar:
push ebp
mov ebp, esp
;What you need to do:
mov eax, DWORD PTR [ebp+8] ;Read the pointer
mov DWORD PTR [eax], 10 ;Deference it
nop
pop ebp
ret
foo:
push ebp
mov ebp, esp
;What you are doing:
mov DWORD PTR [ebp+8], 10 ;Overwriting an argument
nop
pop ebp
ret
main:
push ebp
mov ebp, esp
;This is you call exactly
push OFFSET FLAT:myVar
call bar
add esp, 4
;How one would call the foo version
mov eax, DWORD PTR myVar
push eax
call foo
add esp, 4
mov eax, 0
leave
ret
Pay particular attention to what C code foo
and bar
correspond to.
This may help you understand the differences.
add a comment |
Regarding your try,
mov OFFSET[ebp+8], 10
Indirect or indexed operands are invalid for the OFFSET
operator, i think you have misunderstood the return value of OFFSET
which is an immediate operand, "effective address of data", also the return value of an OFFSET
operator would make the destination operand of the MOV
instruction an immediate operand which is invalid.
In your case if you have an offset of variableName
already on the stack, first load the offset in a temporary register and just use an indirect operand dereference but you have to specify the the size by using PTR
operator.
mov esi,[ebp+8]
mov DWORD PTR[esi],10
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53423003%2fchanging-a-variable-whose-address-is-in-stack%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
You are pushing a pointer, as noted in the comment you need to deference it.
Refer to this Godbolt example where this C code
void bar(int* c)
{
*c = 10;
}
void foo(int c)
{
c = 10;
}
int myVar;
int main()
{
bar(&myVar);
foo(myVar);
}
is assembled into
bar:
push ebp
mov ebp, esp
;What you need to do:
mov eax, DWORD PTR [ebp+8] ;Read the pointer
mov DWORD PTR [eax], 10 ;Deference it
nop
pop ebp
ret
foo:
push ebp
mov ebp, esp
;What you are doing:
mov DWORD PTR [ebp+8], 10 ;Overwriting an argument
nop
pop ebp
ret
main:
push ebp
mov ebp, esp
;This is you call exactly
push OFFSET FLAT:myVar
call bar
add esp, 4
;How one would call the foo version
mov eax, DWORD PTR myVar
push eax
call foo
add esp, 4
mov eax, 0
leave
ret
Pay particular attention to what C code foo
and bar
correspond to.
This may help you understand the differences.
add a comment |
You are pushing a pointer, as noted in the comment you need to deference it.
Refer to this Godbolt example where this C code
void bar(int* c)
{
*c = 10;
}
void foo(int c)
{
c = 10;
}
int myVar;
int main()
{
bar(&myVar);
foo(myVar);
}
is assembled into
bar:
push ebp
mov ebp, esp
;What you need to do:
mov eax, DWORD PTR [ebp+8] ;Read the pointer
mov DWORD PTR [eax], 10 ;Deference it
nop
pop ebp
ret
foo:
push ebp
mov ebp, esp
;What you are doing:
mov DWORD PTR [ebp+8], 10 ;Overwriting an argument
nop
pop ebp
ret
main:
push ebp
mov ebp, esp
;This is you call exactly
push OFFSET FLAT:myVar
call bar
add esp, 4
;How one would call the foo version
mov eax, DWORD PTR myVar
push eax
call foo
add esp, 4
mov eax, 0
leave
ret
Pay particular attention to what C code foo
and bar
correspond to.
This may help you understand the differences.
add a comment |
You are pushing a pointer, as noted in the comment you need to deference it.
Refer to this Godbolt example where this C code
void bar(int* c)
{
*c = 10;
}
void foo(int c)
{
c = 10;
}
int myVar;
int main()
{
bar(&myVar);
foo(myVar);
}
is assembled into
bar:
push ebp
mov ebp, esp
;What you need to do:
mov eax, DWORD PTR [ebp+8] ;Read the pointer
mov DWORD PTR [eax], 10 ;Deference it
nop
pop ebp
ret
foo:
push ebp
mov ebp, esp
;What you are doing:
mov DWORD PTR [ebp+8], 10 ;Overwriting an argument
nop
pop ebp
ret
main:
push ebp
mov ebp, esp
;This is you call exactly
push OFFSET FLAT:myVar
call bar
add esp, 4
;How one would call the foo version
mov eax, DWORD PTR myVar
push eax
call foo
add esp, 4
mov eax, 0
leave
ret
Pay particular attention to what C code foo
and bar
correspond to.
This may help you understand the differences.
You are pushing a pointer, as noted in the comment you need to deference it.
Refer to this Godbolt example where this C code
void bar(int* c)
{
*c = 10;
}
void foo(int c)
{
c = 10;
}
int myVar;
int main()
{
bar(&myVar);
foo(myVar);
}
is assembled into
bar:
push ebp
mov ebp, esp
;What you need to do:
mov eax, DWORD PTR [ebp+8] ;Read the pointer
mov DWORD PTR [eax], 10 ;Deference it
nop
pop ebp
ret
foo:
push ebp
mov ebp, esp
;What you are doing:
mov DWORD PTR [ebp+8], 10 ;Overwriting an argument
nop
pop ebp
ret
main:
push ebp
mov ebp, esp
;This is you call exactly
push OFFSET FLAT:myVar
call bar
add esp, 4
;How one would call the foo version
mov eax, DWORD PTR myVar
push eax
call foo
add esp, 4
mov eax, 0
leave
ret
Pay particular attention to what C code foo
and bar
correspond to.
This may help you understand the differences.
answered Nov 22 '18 at 7:44
Margaret BloomMargaret Bloom
22k42966
22k42966
add a comment |
add a comment |
Regarding your try,
mov OFFSET[ebp+8], 10
Indirect or indexed operands are invalid for the OFFSET
operator, i think you have misunderstood the return value of OFFSET
which is an immediate operand, "effective address of data", also the return value of an OFFSET
operator would make the destination operand of the MOV
instruction an immediate operand which is invalid.
In your case if you have an offset of variableName
already on the stack, first load the offset in a temporary register and just use an indirect operand dereference but you have to specify the the size by using PTR
operator.
mov esi,[ebp+8]
mov DWORD PTR[esi],10
add a comment |
Regarding your try,
mov OFFSET[ebp+8], 10
Indirect or indexed operands are invalid for the OFFSET
operator, i think you have misunderstood the return value of OFFSET
which is an immediate operand, "effective address of data", also the return value of an OFFSET
operator would make the destination operand of the MOV
instruction an immediate operand which is invalid.
In your case if you have an offset of variableName
already on the stack, first load the offset in a temporary register and just use an indirect operand dereference but you have to specify the the size by using PTR
operator.
mov esi,[ebp+8]
mov DWORD PTR[esi],10
add a comment |
Regarding your try,
mov OFFSET[ebp+8], 10
Indirect or indexed operands are invalid for the OFFSET
operator, i think you have misunderstood the return value of OFFSET
which is an immediate operand, "effective address of data", also the return value of an OFFSET
operator would make the destination operand of the MOV
instruction an immediate operand which is invalid.
In your case if you have an offset of variableName
already on the stack, first load the offset in a temporary register and just use an indirect operand dereference but you have to specify the the size by using PTR
operator.
mov esi,[ebp+8]
mov DWORD PTR[esi],10
Regarding your try,
mov OFFSET[ebp+8], 10
Indirect or indexed operands are invalid for the OFFSET
operator, i think you have misunderstood the return value of OFFSET
which is an immediate operand, "effective address of data", also the return value of an OFFSET
operator would make the destination operand of the MOV
instruction an immediate operand which is invalid.
In your case if you have an offset of variableName
already on the stack, first load the offset in a temporary register and just use an indirect operand dereference but you have to specify the the size by using PTR
operator.
mov esi,[ebp+8]
mov DWORD PTR[esi],10
edited Nov 28 '18 at 5:36
answered Nov 22 '18 at 7:35
Biological FSMBiological FSM
214
214
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53423003%2fchanging-a-variable-whose-address-is-in-stack%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
You need another dereference. Load the address into a scratch register and then deref that.
– Peter Cordes
Nov 22 '18 at 2:39