【发布时间】:2017-10-11 19:51:26
【问题描述】:
鉴于这个项目——我正在帮助的一个学生的项目——
global _start
section .text
_start:
mov ebx, people
mov eax, [ebx + 2]
add eax, [ebx + 4]
add eax, [ebx + 6]
add eax, [ebx + 8]
mov ebx, [constant]
div bx
section .data
average dw 0
constant dw 5
people dw 0, 10, 25, 55, 125
在将其从 Visual Studio 移植到 Linux 机器以找出问题所在时,我遇到了一些问题:
1) 为什么gdm在发出print $ax的时候显示总和255,而发出print $eax的命令时却出现一个大数字?是不是因为我们添加了 word 值而不是 longword 值?
我确实尝试添加到 ax,而不是 eax,并得到了相同的结果。当我试图将初始值移动到 ax 时,我收到了搬迁投诉。这就是我使用 eax 的原因。
2) 为什么使用div bx 时的商是43,但使用div ebx 时会得到错误的答案?
顺便说一句,我相信我找到了最初的问题,即整数溢出。第 10 行 -- mov ebx, [constant] -- 最初是 mov ebx,constant,这并没有导致将 5 移动到 bx 中。
【问题讨论】:
-
您正在从具有 16 位偏移量的位置加载 32 位 (
eax)。这使您的值重叠。 -
div的工作方式不同,请查看说明指南。或搜索堆栈溢出(通常每月大约弹出 2-5 次)。而且您的代码不会终止(只要您只在调试器中跳过它,没关系,只是不要运行它)。 -
@BoPersson 当我使用 ax 时,同样的事情发生了——添加单词值。我尝试了很多不同的东西。
-
movzx ecx, word [ebx + 4]; add eax, ecx等等。 -
并且
mov ebx,constant将被 NASM 翻译成,在我的偏见看来,mov ebx, "address of label constant"的正确形式。由于 Intel 语法要求使用方括号[address expression]来标记内存访问。不幸的是,有一大群 x86 汇编器(MASM、emu8086、MASM 模式下的 TASM,...)试图变得聪明,并且充当mov ebx,constant是“获取变量”。要获得地址,您必须使用关键字offset:mov ebx,offset constant。 NASM 更干净,需要[]使用,因此您可以在读取源时轻松查看每个内存访问。
标签: visual-studio assembly x86 nasm