我正在自学一些使用 x86-64 Mac OS 的汇编编程。我试图弄清楚为什么在将正整数除以负整数时会溢出。例如,5/-2必须返回-2。但是,就我而言,它2147483371在我执行时返回 a-554/2而不是-277...这是我的程序集文件中的内容:
; compiling using: nasm -f macho64 -o divide.o divide.s
[bits 64]
global _divide
section .text
; int divide(int dividend, int divisor)
_divide:
xor rdx, rdx ; making this to 0
push rbp ; base stack pointer
mov rax, rdi ; dividend
mov rcx, rsi ; divisor
idiv rcx ; integer division
add rsp, 8
ret
Run Code Online (Sandbox Code Playgroud)
在我的main.c文件中,我有这个:
#include <stdio.h>
extern int divide(int dividend, …Run Code Online (Sandbox Code Playgroud) 我刚刚尝试了这个问题,要求你解释一下代码行有什么问题:
movl %eax, %rdx
Run Code Online (Sandbox Code Playgroud)
解决方案表明目标操作数的大小错误。
仅当从较大尺寸变为较小尺寸时才“非法”,还是源操作数和目标操作数对于所有指令(或至少 mov 类类型)必须具有相同的尺寸?
我正在从《计算机系统:程序员的视角》学习 x86-64 汇编,并且遇到了一个练习,要求将一行 C 代码转换为(两个)等效的汇编指令。该代码是关于使用指针将一种类型的变量复制到另一种类型的变量。
指针变量声明如下:
src_t *sp; //src_t and dest_t are typedefs
dest_t *dp;
Run Code Online (Sandbox Code Playgroud)
需要翻译的C代码是:
*dp = (dest_t)*sp;
Run Code Online (Sandbox Code Playgroud)
假设指针sp和分别dp存储在寄存器%rdi和%rsi中,并且我们应该设置%rax(例如 、%eax或%ax)的“适当部分”%al来进行中间数据复制(因为 x86-64 不允许源和目标同时复制)是内存引用)。
现在,当src_tisunsigned char和dest_tis 时long,我为其编写了以下汇编代码:
movzbq (%rdi), %rax //move a byte into %rax with zero extension
movq %rax, (%rsi) //move 8 bytes of 'long' data
Run Code Online (Sandbox Code Playgroud)
但这本书以及Godboltgcc (与 一起使用-O3)都说它应该是
movzbl (%rdi), %eax …Run Code Online (Sandbox Code Playgroud) 我正在研究基本的 shell 代码和orw代码。
但是,在此过程中,我收到以下错误消息:
错误:不支持的指令
mov
这是我的 C 和汇编代码框架:
// File name: orw.c
// Compile: gcc -o orw orw.c -masm=intel
__asm__(
".global run_sh\n"
"run_sh:\n"
"push 0x67\n"
"mov rax, 0x616c662f706d742f \n"
"push rax\n"
"mov rdi, rsp\n"
"xor rsi, rsi\n"
"xor rdx, rdx\n"
"xor eax, eax\n"
"mov eax, 2\n"
"syscall"
"\n"
"mov rdi, eax\n"
"mov rsi, rsp\n"
"sub rsi, 0x30\n"
"mov rdx, 0x30\n"
"xor eax, eax\n"
"syscall"
"\n"
"mov rdi,1\n"
"mov eax,1\n"
"syscall"
);
void run_sh();
int main() { run_sh(); …Run Code Online (Sandbox Code Playgroud) 使用Z2 dword ?,mov eax, Z2工作正常,但movzx eax, Z2会出现“无效指令操作数”错误。
我在这里有点困惑:即使Z2的大小与 相同eax,为什么程序集不能接受movzx这个?似乎movzx特别希望操作数的大小不同。
设计这样的指令的原因可能是什么?
如果它被设计为简单地允许相同大小的操作数,那么编码不是更容易吗?