我想把c和汇编代码结合起来。
我有下面的C代码:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
extern void _increment(unsigned short *x);
int main(int argc, char** argv)
{
unsigned short x = 0;
_increment(&x);
printf("%d", x)
return 0;
}
和汇编(32位NASM)代码:
section .text
global _increment
_increment:
push ebx
mov bx, word [esp+8] ;what is stored in bx here? the x address?
mov ax, [bx] ;what is stored in ax here? the x value?
;add word [esp+8], 1 -> dosnt work
pop ebx
ret
section .data
如果我执行这个命令,我会得到一个分段错误。2有人能解释一下寄存器/堆栈中存储了什么吗?3也许我可以增加值而不是X的地址?
1条答案
按热度按时间9rnv2umw1#
很明显你了解指针的工作原理,唯一的错误是指针本身的大小,在几乎所有的CPU上,指针的大小(不是它所指向的对象的大小)将等于指令指针寄存器的大小(在非x86架构上通常称为PC,表示程序计数器)。此规则也有例外,但通常它只会匹配你硬件的默认寄存器大小,这就是为什么,正如你在注解中提到的,你只加载了一半的指针,因为你使用
bx
作为你从栈加载的目的地,在x86中,不在括号中的寄存器操作数决定了读写内存的字节数,这就是为什么即使esp
是32位,bx
是16位,当你执行mov bx, word [esp+8]
时,你也不会因为操作数大小不匹配而得到汇编错误;右操作数是16位存储器而不是32位寄存器。