Как получить доступ к элементу, присутствующему в стеке, используя bp, после создания локальной переменной?

Я использую NASM 8086. Как я могу получить доступ к третьему и четвертому элементам, представленным в стеке, используя bp? Вот мой код

mov ax, 1
push ax  ; 1st element on stack
mov ax, 2; 2nd element on stack
push ax

push bp ; save old value of bp
mov bp, sp ; make bp our reference point
sub sp, 2 ; creates a local variable,it can be accessed by [bp-2]

mov bx,3
push bx ; 3rd element on stack
mov cx,4
push cx ; 4th element on stack

mov bx, [bp+6] ; load 1st element in bx
mov cx, [bp+4] ; load 2nd element in cx
mov ax, [bp-2] ; load local variable in ax

Теперь, как написать bp для доступа к 3-му и 4-му элементам в стеке

2 ответа

Решение

То, что вы называете 3-й элемент будет в [bp-4]и "четвертый" будет [bp-6],

Если вы хотите, чтобы ваша подпрограмма получила 4 аргумента, поместите их в стек раньше:

push bp ; save old value of bp
mov bp, sp ; make bp our reference point
sub sp, 2 ; creates a local variable,it can be accessed by [bp-2]

Кроме того, вы должны прекратить свою функцию с помощью:

mov esp, ebp
pop ebp

Этот код:

mov bx,3
push bx ; 3rd element on stack
mov cs,4
push cx ; 4th element on stack

похоже, вы пытаетесь подготовить аргументы для вызова новой функции.

Это должно немного отличаться:

Чтобы соответствовать cdecl (в этом примере используется cdecl) соглашение о вызовах (вам нужно, чтобы, если вы хотите использовать asm с c и т. Д.), Вы должны выдвигать входные аргументы в обратном порядке - скажем, вы хотите 4 входных аргумента (целые числа - 32 бита). Стенограмма вызова функции вызова C/C++ (0xaa,0xbb,0xcc,0xdd) выглядит следующим образом:

push 0DDh   4bytes
push 0CCh
push 0BBh
push 0AAh
call func   // another 'push'
add esp, 10h

Теперь ваша рутина может выглядеть так:

push ebp    //next push
mov ebp, esp

// your args are '2 pushes' away (call, push ebp) = 8 bytes away
// hence 1st arg is [ebp+8], 2nd is [ebp+12], 3rd is [ebp+16], 4th is [ebp+20]
// loading args to regs

mov eax, dword ptr [ebp+8]   // 0xAA - 1st arg
mov ebx, dword ptr [ebp+12]  // 0xBB - 2nd arg
mov ecx, dword ptr [ebp+16]  // 0xCC - 3rd arg
mov edx, dword ptr [ebp+20]  // 0xDD - 4th arg

mov esp, ebp
pop ebp
ret

но если вы хотите использовать локальные переменные - вот как использовать 2 локальные переменные вместе с 4 переменными int, передаваемыми в качестве аргументов:

push ebp
mov ebp, esp

sub esp, 8  // for 2 local int(32bit) variables

mov dword ptr[ebp-4], 3   // set one local var to 3
mov dword ptr[ebp-8], 4   // set one local var to 4

mov eax, dword ptr [ebp+8]   // 0xAA - 1st arg
mov ebx, dword ptr [ebp+12]  // 0xBB - 2nd arg
mov ecx, dword ptr [ebp+16]  // 0xCC - 3rd arg
mov edx, dword ptr [ebp+20]  // 0xDD - 4th arg

add esp, 8 // remove space for local vars

mov esp, ebp
pop ebp
ret
Другие вопросы по тегам