我正在尝试组装一小段 x86 代码。我在 32 位机器上,我编写了以下代码。它应该只是将值添加到 eax 中然后返回。我意识到不会有任何输出。当我编译这个使用
gcc main.S -o main
它编译没有错误。但是当我运行它时会出现段错误(gdb 声称它在第一条 movl 指令上出现段错误)。main.S 中有以下代码。我究竟做错了什么?
.text
.globl main
main:
pushl %ebp
movl %esp, %ebp
movl 0, %eax
addl $3, %eax
addl $3, %eax
leave
ret
Run Code Online (Sandbox Code Playgroud) 我正在尝试切换到intel x86中的保护模式.
我已经用lgdt加载了我的gdt,将cr0的P标志设置为1和所有段选择器但是当我从函数调用返回时,我无法调用任何其他函数或者我得到此错误
qemu: fatal: Trying to execute code outside RAM or ROM at 0xfeeb7c5b
Run Code Online (Sandbox Code Playgroud)
这是我的switch_to_pmode函数:
gdtr:
.short 23 // limit
gdtr_base:
.long 0 // base
switch_to_pmode:
movl $null_segment, %eax // Address of the first byte of the GDT
movl %eax, gdtr_base
cli // disable interrupts
lgdt (gdtr)
movl %cr0, %eax
or $0x1, %eax
movl %eax, %cr0 // Set the PE flag
push $0x8
push $reload_segments
lret
reload_segments:
movl $0x10, %eax
movl %eax, %ds
movl %eax, %ss
movl %eax, %es …Run Code Online (Sandbox Code Playgroud) 尝试运行以下程序集程序时:
.globl start
start:
pushq $0x0
movq $0x1, %rax
subq $0x8, %rsp
int $0x80
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
dyld: no writable segment
Trace/BPT trap
Run Code Online (Sandbox Code Playgroud)
知道是什么原因引起的吗?32位汇编中的类似程序运行良好.
为什么我们有像push和pop这样的命令?
从我的理解pop和push基本上分别做(mov然后add)和(sub然后mov)esp.
例如,不会:
pushl %eax
Run Code Online (Sandbox Code Playgroud)
相当于:
subl $4, %esp
movl %eax, (%esp-4)
Run Code Online (Sandbox Code Playgroud)
请纠正我,如果没有堆栈访问(%esp-4),我还在学习汇编
我能看到的唯一真正的好处是,如果同时进行两种操作都会带来一些好处; 但我不知道它怎么可能.
我正在练习使用汇编编写引导程序(在AT&T语法和gnu/gas中).组装并链接小程序,然后将其复制到虚拟磁盘的第一个扇区.BIOS会加载它0000:7c00,这就是问题所在.在call hello将被转换call 0010到call 7c10运行期间.但是movw $message, %as没有重新安置.现在ax仍然0026没有7c26.结果是我无法Hello World在屏幕上制作.相反,0000:0026屏幕上会显示一些随机数据.
如何在启动过程中使其正确?我应该使用某些指令更改asm源代码吗?或者我应该更改我的链接脚本?
谢谢!
.text
.global _start
.code16
_start:
movw %cs, %ax
movw %ax, %ds
movw %ax, %es
call hello
jmp .
.org 0x10
hello:
movw $message, %ax
movw %ax, %bp
movw $13, %cx
movw $0x1301, %ax
movw $0x000c, %bx
movb $0, %dl
int $0x10
ret
message:
.ascii "Hello, World!"
.org 0x01fe
.byte 0x55
.byte …Run Code Online (Sandbox Code Playgroud) 我在解释这个练习时遇到了一些困难;
xorl在这个程序集片段中做了什么?
C代码:
int i = 0;
if (i>=55)
i++;
else
i--;
Run Code Online (Sandbox Code Playgroud)
部件
xorl ____ , %ebx
cmpl ____ , %ebx
Jel .L2
____ %ebx
.L2:
____ %ebx
.L3:
Run Code Online (Sandbox Code Playgroud)
装配部分发生了什么?
所以我正在尝试编写一些x86来为结构分配内存.我的c代码看起来像这样......
struc *uno = malloc(sizeof(struc));
uno->first = 0;
uno->second = 0;
uno->third = 0;
//And the struct
struct struc {
int first;
int second;
int *third;
}
Run Code Online (Sandbox Code Playgroud)
拆卸看起来像......
pushl %ebp
movl %esp, %ebp
subl $40, %esp
movl $12, (%esp)
call malloc
movl %eax, -12(%ebp)
movl -12(%ebp), %eax
movl $0, (%eax)
movl -12(%ebp), %eax
movl $0, 4(%eax)
movl -12(%ebp), %eax
movl $0, 8(%eax)
movl $0, %eax
Run Code Online (Sandbox Code Playgroud)
所以我有几个问题......
1)结构的大小是16,但为什么程序集只显示它分配12?
2)这是什么意思
movl %eax, -12(%ebp)
movl -12(%ebp), %eax
Run Code Online (Sandbox Code Playgroud)
是不是只是将eax的内容放入ebp-12的地址中.那么第二个语句是多余的?
3)当没有其他局部变量或参数被推入堆栈时,为什么esp会减少40?我以为它只需要递减16.
任何帮助表示赞赏,以及我认为您认为相关的任何内容.我对装配很新.谢谢.
Linux 64. AT&T.
GCC 4.8.2(-O3 -march = native)
左手下方的x86_64 abi,在第21页打开.
为了明确意图,这里有一个想法:
int32_t res[] = {0,0,0,0};
int32_t primo[] = {5,8,50,150};
for (int32_t x = 0; x < 4; ++x) {
res[x] = primo[x];
}
printf("%d %d %d %d\n", res[0], res[1], res[2], res[3]);
Run Code Online (Sandbox Code Playgroud)
检测到错误:
Error: `(%rsp,%esi,4)' is not a valid base/index expression
Run Code Online (Sandbox Code Playgroud)
代码 :
int32_t res[] = {0,0,0,0};
int32_t primo[] = {5,8,50,150};
int32_t counter = 0;
__asm__ volatile(
"start_loop:\n\t"
"movl (%1,%2,4), (%0,%2,4)\n\t"
"addl $1, %2\n\t"
"cmp $4, %2\n\t"
"jne …Run Code Online (Sandbox Code Playgroud) 我目前正在学习汇编和C编程语言,我有几个问题.
C代码
int arith(int x, int y, int z) {
int t1 = x + y;
int t2 = z*48;
int t3 = t1 & 0xFFFF;
int t4 = t2 * t3;
return t4;
}
Run Code Online (Sandbox Code Playgroud)
汇编代码
movl 16(%ebp),%eax z
leal (%eax,%eax,2), %eax z*3
sall $4,%eax t2 = z*48
movl 12(%ebp),%edx y
addl 8(%ebp),%edx t1 = x+y
andl $65535,%edx t3 = t1&0xFFFF
imull %edx,%eax Return t4 = t2*t3
Run Code Online (Sandbox Code Playgroud)
而不是使用leal然后移动4乘以z乘以48,我可以使用imull $ 48,%eax吗?
此外,这是多次使用%edx寄存器.这是否意味着t1被覆盖?换句话说,如果我愿意,我还能在t4之前检索t1吗?